Commit 826df076a31 for nodejs
commit 826df076a318c4078f3943209d30b9f5f2d85dfa
Author: Joyee Cheung <joyeec9h3@gmail.com>
Date: Mon Oct 12 14:05:12 2026 +0200
deps: update V8 to 15.6.75.13
PR-URL: https://github.com/nodejs/node/pull/66601
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS
index ee6d6af3a38..31ac08aa8dd 100644
--- a/deps/v8/AUTHORS
+++ b/deps/v8/AUTHORS
@@ -45,6 +45,7 @@ CodeWeavers, Inc. <*@codeweavers.com>
Alibaba, Inc. <*@alibaba-inc.com>
SiFive, Inc. <*@sifive.com>
Island Technology, Inc. <*@island.io>
+Xperi Corporation <*@xperi.com>
Aapo Alasuutari <aapo.alasuutari@gmail.com>
Aaron Bieber <deftly@gmail.com>
@@ -105,6 +106,7 @@ Chris Nardi <hichris123@gmail.com>
Christopher A. Taylor <chris@gameclosure.com>
Christopher Nady <nady.christopher@gmail.com>
Colin Ihrig <cjihrig@gmail.com>
+Colin McDonnell <colinmcd94@gmail.com>
Cong Zuo <zckevinzc@gmail.com>
Craig Schlenter <craig.schlenter@gmail.com>
Cristiano Moraes <cris.moraes.ds@gmail.com>
@@ -300,6 +302,7 @@ Sam James <sam@gentoo.org>
Samuel Attard <samuel.r.attard@gmail.com>
Sébastien Doeraene <sjrdoeraene@gmail.com>
Seo Sanghyeon <sanxiyn@gmail.com>
+Seongjin Kim <mirusu400@gmail.com>
Sergey Markelov <sergionso@gmail.com>
Shawn Anastasio <shawnanastasio@gmail.com>
Shawn Presser <shawnpresser@gmail.com>
@@ -310,6 +313,7 @@ Stefan Penner <stefan.penner@gmail.com>
Stefan Stojanovic <stefko.stojanovic@gmail.com>
Stephan Hartmann <stha09@googlemail.com>
Stephen Belanger <stephen.belanger@datadoghq.com>
+Stephen Jayna <stephen.jayna@entaingroup.com>
Steven R. Loomis <srl295@gmail.com>
Sylvestre Ledru <sledru@mozilla.com>
Takeshi Yoneda <takeshi@tetrate.io>
@@ -355,6 +359,7 @@ Yong Wang <ccyongwang@tencent.com>
Youfeng Hao <ajihyf@gmail.com>
Yu Yin <xwafish@gmail.com>
Yujie Wang <hex6770@gmail.com>
+Yun Jiyun <tomatoziiilll@gmail.com>
Yuri Iozzelli <yuri@leaningtech.com>
Yuri Gaevsky <yuri.gaevsky@syntacore.com>
Yusif Khudhur <yusif.khudhur@gmail.com>
diff --git a/deps/v8/BUILD.bazel b/deps/v8/BUILD.bazel
index 2350f14126e..914fe144311 100644
--- a/deps/v8/BUILD.bazel
+++ b/deps/v8/BUILD.bazel
@@ -183,7 +183,7 @@ v8_flag(name = "v8_enable_experimental_tq_to_tsa")
# off, the metagen action is not part of the build graph.
v8_flag(
name = "v8_use_metagen_instance_types",
- default = False,
+ default = True,
)
v8_flag(
@@ -797,6 +797,7 @@ filegroup(
"include/v8-maybe.h",
"include/v8-memory-span.h",
"include/v8-message.h",
+ "include/v8-metrics.h",
"include/v8-microtask.h",
"include/v8-microtask-queue.h",
"include/v8-object.h",
@@ -815,6 +816,7 @@ filegroup(
"include/v8-traced-handle.h",
"include/v8-typed-array.h",
"include/v8-unwinder.h",
+ "include/v8-unwinder-state.h",
"include/v8-util.h",
"include/v8-value.h",
"include/v8-value-serializer.h",
@@ -1652,6 +1654,8 @@ filegroup(
"src/date/dateparser-inl.h",
"src/debug/debug.cc",
"src/debug/debug.h",
+ "src/debug/debug-block-list.cc",
+ "src/debug/debug-block-list.h",
"src/debug/debug-coverage.cc",
"src/debug/debug-coverage.h",
"src/debug/debug-evaluate.cc",
@@ -2608,6 +2612,7 @@ filegroup(
"src/sandbox/external-pointer-table-inl.h",
"src/sandbox/cppheap-pointer.h",
"src/sandbox/cppheap-pointer-inl.h",
+ "src/sandbox/cppheap-pointer-tag.h",
"src/sandbox/cppheap-pointer-table.cc",
"src/sandbox/cppheap-pointer-table.h",
"src/sandbox/cppheap-pointer-table-inl.h",
diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn
index 78035a8caf9..1df3d4e31bc 100644
--- a/deps/v8/BUILD.gn
+++ b/deps/v8/BUILD.gn
@@ -38,10 +38,6 @@ if (is_ios) {
import("//build/config/apple/mobile_config.gni") # For `target_platform`.
}
-if (!build_with_v8_embedder && !(defined(build_with_node) && build_with_node)) {
- import("//third_party/partition_alloc/partition_alloc.gni")
-}
-
# For faster Windows builds. See https://crbug.com/v8/8475.
emit_builtins_as_inline_asm = is_win && is_clang
@@ -204,6 +200,10 @@ declare_args() {
# to when v8_enable_static_roots is enabled.
v8_enable_static_roots_generation = false
+ # Enables a separate TdzHole root for Temporal Dead Zone initialization and
+ # checks instead of aliasing TheHole.
+ v8_enable_tdz_hole = true
+
# Enable code-generation-time checking of types in the CodeStubAssembler.
v8_enable_verify_csa = false
@@ -885,6 +885,10 @@ assert(
!v8_enable_memory_corruption_api || !is_lsan,
"The Memory Corruption API cannot be enabled together with LSan as both attach to the d8 process via ptrace")
+# ASan sandbox crash filters aren't wired up properly in component builds.
+assert(!v8_enable_memory_corruption_api || !is_component_build,
+ "The Memory Corruption API cannot be enabled in a component build")
+
assert(!v8_enable_sandbox_hardware_support || v8_enable_sandbox,
"The sandbox must be enabled to enable sandbox hardware support")
@@ -1623,6 +1627,9 @@ config("features") {
if (v8_enable_static_roots_generation) {
defines += [ "V8_STATIC_ROOTS_GENERATION" ]
}
+ if (v8_enable_tdz_hole) {
+ defines += [ "V8_ENABLE_TDZ_HOLE" ]
+ }
if (v8_use_zlib) {
defines += [ "V8_USE_ZLIB" ]
}
@@ -1677,12 +1684,6 @@ config("features") {
if (v8_function_arguments_caller_are_own_props) {
defines += [ "V8_FUNCTION_ARGUMENTS_CALLER_ARE_OWN_PROPS" ]
}
- if (!build_with_v8_embedder &&
- !(defined(build_with_node) && build_with_node)) {
- if (enable_user_space_zero_segment) {
- defines += [ "PA_ENABLE_USER_SPACE_ZERO_SEGMENT" ]
- }
- }
}
config("toolchain") {
@@ -2529,6 +2530,12 @@ if (v8_use_metagen_instance_types) {
"tools/metagen/instance_types.py",
"tools/metagen/metagen.py",
_metagen_driver_file,
+
+ # The driver's aggregate header. It declares no classes, so
+ # metagen records no fact from it and it is absent from the
+ # depfile, but its include list determines which headers the
+ # harvest parses. PRESUBMIT.py checks that the list is complete.
+ "src/objects/all-objects.h",
"$root_out_dir/v8_build_config.json",
# Proxy for the whole builtin-header directory, which has no
@@ -2884,6 +2891,7 @@ v8_cluster_source_set("torque_generated_initializers") {
":generate_bytecode_builtins_list",
":run_torque",
":v8_base_without_compiler",
+ ":v8_internal_headers",
":v8_maybe_temporal",
":v8_tracing",
]
@@ -3565,6 +3573,7 @@ v8_cluster_source_set("v8_initializers") {
deps = [
":torque_generated_initializers",
":v8_base_without_compiler",
+ ":v8_internal_headers",
":v8_shared_internal_headers",
":v8_tracing",
]
@@ -3743,6 +3752,7 @@ v8_source_set("v8_init") {
deps = [
":v8_base_without_compiler",
":v8_initializers",
+ ":v8_internal_headers",
":v8_maybe_temporal",
":v8_tracing",
]
@@ -3825,6 +3835,7 @@ v8_header_set("v8_headers") {
"include/v8-maybe.h",
"include/v8-memory-span.h",
"include/v8-message.h",
+ "include/v8-metrics.h",
"include/v8-microtask-queue.h",
"include/v8-microtask.h",
"include/v8-object.h",
@@ -3840,9 +3851,9 @@ v8_header_set("v8_headers") {
"include/v8-snapshot.h",
"include/v8-statistics.h",
"include/v8-template.h",
- "include/v8-trace-categories.h",
"include/v8-traced-handle.h",
"include/v8-typed-array.h",
+ "include/v8-unwinder-state.h",
"include/v8-unwinder.h",
"include/v8-util.h",
"include/v8-value-serializer.h",
@@ -3864,7 +3875,6 @@ v8_header_set("v8_headers") {
deps = [
":cppgc_headers",
- ":v8_tracing",
":v8_version",
]
}
@@ -4306,6 +4316,7 @@ v8_header_set("v8_internal_headers") {
"src/date/date.h",
"src/date/dateparser-inl.h",
"src/date/dateparser.h",
+ "src/debug/debug-block-list.h",
"src/debug/debug-coverage.h",
"src/debug/debug-evaluate.h",
"src/debug/debug-frames.h",
@@ -4908,6 +4919,7 @@ v8_header_set("v8_internal_headers") {
"src/sandbox/cppheap-pointer-inl.h",
"src/sandbox/cppheap-pointer-table-inl.h",
"src/sandbox/cppheap-pointer-table.h",
+ "src/sandbox/cppheap-pointer-tag.h",
"src/sandbox/cppheap-pointer.h",
"src/sandbox/external-entity-table-inl.h",
"src/sandbox/external-entity-table.h",
@@ -5473,6 +5485,7 @@ v8_header_set("v8_internal_headers") {
"src/codegen/mips64/assembler-mips64-inl.h",
"src/codegen/mips64/assembler-mips64.h",
"src/codegen/mips64/constants-mips64.h",
+ "src/codegen/mips64/interface-descriptors-mips64-inl.h",
"src/codegen/mips64/macro-assembler-mips64.h",
"src/codegen/mips64/register-mips64.h",
"src/codegen/mips64/reglist-mips64.h",
@@ -5494,6 +5507,7 @@ v8_header_set("v8_internal_headers") {
"src/codegen/loong64/assembler-loong64-inl.h",
"src/codegen/loong64/assembler-loong64.h",
"src/codegen/loong64/constants-loong64.h",
+ "src/codegen/loong64/interface-descriptors-loong64-inl.h",
"src/codegen/loong64/macro-assembler-loong64.h",
"src/codegen/loong64/register-loong64.h",
"src/codegen/loong64/reglist-loong64.h",
@@ -5686,6 +5700,36 @@ v8_header_set("v8_internal_headers") {
}
}
+ if (is_win && v8_enable_etw_stack_walking) {
+ sources += [
+ "src/diagnostics/etw-debug-win.h",
+ "src/diagnostics/etw-isolate-capture-state-monitor-win.h",
+ "src/diagnostics/etw-isolate-load-script-data-win.h",
+ "src/diagnostics/etw-isolate-operations-win.h",
+ "src/diagnostics/etw-jit-metadata-win.h",
+ "src/diagnostics/etw-jit-win.h",
+ ]
+ }
+
+ if (v8_enable_generated_code_validator) {
+ sources += [ "src/sandbox/generated-code-validator.h" ]
+ }
+
+ if (v8_fuzzilli) {
+ sources += [ "src/fuzzilli/fuzzilli.h" ]
+ }
+
+ if (v8_dumpling) {
+ sources += [
+ "src/dumpling/dumpling-manager.h",
+ "src/dumpling/object-dumping.h",
+ ]
+ }
+
+ if (v8_enable_vtunetracemark && (is_linux || is_chromeos || is_win)) {
+ sources += [ "src/extensions/vtunedomain-support-extension.h" ]
+ }
+
frameworks = []
# BrowserEngineKit only exists on iOS itself, not on tvOS and other
@@ -5908,7 +5952,6 @@ if (!v8_enable_maglev) {
"src/maglev/maglev-range-verification.cc",
"src/maglev/maglev-truncation.cc",
"src/maglev/turbolev-escape-analysis.cc",
- "src/maglev/turbolev-escape-analysis.h",
]
}
@@ -6086,6 +6129,9 @@ v8_cluster_source_set("v8_compiler_for_mksnapshot_source_set") {
v8_cluster_source_set("v8_compiler") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
+ # Do not publicize any header to remove build dependency.
+ public = []
+
if (v8_enable_turbofan) {
sources = v8_compiler_sources
} else {
@@ -6150,6 +6196,9 @@ v8_cluster_source_set("v8_base_without_compiler") {
"tools/gcmole/:*",
]
+ # Do not publicize any header to remove build dependency.
+ public = []
+
# Split static libraries on windows into two.
split_count = 2
@@ -6263,6 +6312,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/compiler/linkage.cc",
"src/date/date.cc",
"src/date/dateparser.cc",
+ "src/debug/debug-block-list.cc",
"src/debug/debug-coverage.cc",
"src/debug/debug-evaluate.cc",
"src/debug/debug-frames.cc",
@@ -6970,7 +7020,6 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/codegen/mips64/assembler-mips64.cc",
"src/codegen/mips64/constants-mips64.cc",
"src/codegen/mips64/cpu-mips64.cc",
- "src/codegen/mips64/interface-descriptors-mips64-inl.h",
"src/codegen/mips64/macro-assembler-mips64.cc",
"src/deoptimizer/mips64/deoptimizer-mips64.cc",
"src/diagnostics/mips64/disasm-mips64.cc",
@@ -6985,7 +7034,6 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/codegen/loong64/assembler-loong64.cc",
"src/codegen/loong64/constants-loong64.cc",
"src/codegen/loong64/cpu-loong64.cc",
- "src/codegen/loong64/interface-descriptors-loong64-inl.h",
"src/codegen/loong64/macro-assembler-loong64.cc",
"src/deoptimizer/loong64/deoptimizer-loong64.cc",
"src/diagnostics/loong64/disasm-loong64.cc",
@@ -7119,23 +7167,15 @@ v8_cluster_source_set("v8_base_without_compiler") {
}
# Architecture independent but platform-specific sources
- if (is_win) {
- if (v8_enable_etw_stack_walking) {
- sources += [
- "src/diagnostics/etw-debug-win.cc",
- "src/diagnostics/etw-debug-win.h",
- "src/diagnostics/etw-isolate-capture-state-monitor-win.cc",
- "src/diagnostics/etw-isolate-capture-state-monitor-win.h",
- "src/diagnostics/etw-isolate-load-script-data-win.cc",
- "src/diagnostics/etw-isolate-load-script-data-win.h",
- "src/diagnostics/etw-isolate-operations-win.cc",
- "src/diagnostics/etw-isolate-operations-win.h",
- "src/diagnostics/etw-jit-metadata-win.cc",
- "src/diagnostics/etw-jit-metadata-win.h",
- "src/diagnostics/etw-jit-win.cc",
- "src/diagnostics/etw-jit-win.h",
- ]
- }
+ if (is_win && v8_enable_etw_stack_walking) {
+ sources += [
+ "src/diagnostics/etw-debug-win.cc",
+ "src/diagnostics/etw-isolate-capture-state-monitor-win.cc",
+ "src/diagnostics/etw-isolate-load-script-data-win.cc",
+ "src/diagnostics/etw-isolate-operations-win.cc",
+ "src/diagnostics/etw-jit-metadata-win.cc",
+ "src/diagnostics/etw-jit-win.cc",
+ ]
}
configs = [
@@ -7160,10 +7200,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
]
if (v8_enable_generated_code_validator) {
- sources += [
- "src/sandbox/generated-code-validator.cc",
- "src/sandbox/generated-code-validator.h",
- ]
+ sources += [ "src/sandbox/generated-code-validator.cc" ]
if (v8_current_cpu == "x64") {
deps += [ "//third_party/fadec" ]
sources += [ "src/sandbox/generated-code-validator-x64.cc" ]
@@ -7188,19 +7225,14 @@ v8_cluster_source_set("v8_base_without_compiler") {
}
if (v8_fuzzilli) {
- sources += [
- "src/fuzzilli/fuzzilli.cc",
- "src/fuzzilli/fuzzilli.h",
- ]
+ sources += [ "src/fuzzilli/fuzzilli.cc" ]
public_deps += [ ":fuzzilli_cov" ]
}
if (v8_dumpling) {
sources += [
"src/dumpling/dumpling-manager.cc",
- "src/dumpling/dumpling-manager.h",
"src/dumpling/object-dumping.cc",
- "src/dumpling/object-dumping.h",
]
}
@@ -7266,10 +7298,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
}
if (v8_enable_vtunetracemark && (is_linux || is_chromeos || is_win)) {
- sources += [
- "src/extensions/vtunedomain-support-extension.cc",
- "src/extensions/vtunedomain-support-extension.h",
- ]
+ sources += [ "src/extensions/vtunedomain-support-extension.cc" ]
deps += [ "third_party/vtune:v8_vtune_trace_mark" ]
}
}
@@ -7751,11 +7780,22 @@ v8_component("v8_libbase") {
# TODO(infra): Add support for qnx, freebsd, openbsd, netbsd, and solaris.
}
-v8_component("v8_libplatform") {
+v8_header_set("v8_libplatform_headers") {
sources = [
"include/libplatform/libplatform-export.h",
"include/libplatform/libplatform.h",
"include/libplatform/v8-tracing.h",
+ ]
+
+ configs = [ ":internal_config_base" ]
+
+ public_configs = [ ":libplatform_config" ]
+
+ deps = [ ":v8_config_headers" ]
+}
+
+v8_component("v8_libplatform") {
+ sources = [
"src/libplatform/default-foreground-task-runner.cc",
"src/libplatform/default-foreground-task-runner.h",
"src/libplatform/default-job.cc",
@@ -7792,7 +7832,7 @@ v8_component("v8_libplatform") {
public_configs = [ ":libplatform_config" ]
- public_deps = []
+ public_deps = [ ":v8_libplatform_headers" ]
deps = [
":v8_config_headers",
@@ -7844,6 +7884,7 @@ v8_source_set("fuzzer_support") {
public_deps = [
":v8",
+ ":v8_internal_headers",
":v8_libbase",
":v8_libplatform",
":v8_maybe_icu",
@@ -8009,7 +8050,7 @@ v8_header_set("cppgc_headers") {
deps = [
":v8_libbase",
- ":v8_libplatform",
+ ":v8_libplatform_headers",
]
if (current_os == "zos" && is_component_build) {
@@ -8151,6 +8192,7 @@ v8_cluster_source_set("cppgc_base") {
if (v8_use_perfetto) {
sources += [
+ "include/v8-trace-categories.h",
"src/tracing/perfetto-sdk.h",
"src/tracing/trace-categories.cc",
"src/tracing/trace-categories.h",
@@ -8219,6 +8261,7 @@ if (v8_enable_webassembly) {
v8_static_library("wee8") {
deps = [
":v8_base",
+ ":v8_internal_headers",
":v8_libbase",
":v8_libplatform",
":v8_shared_internal_headers",
@@ -8306,6 +8349,7 @@ if (current_toolchain == v8_snapshot_toolchain) {
":v8_base_without_compiler",
":v8_compiler_for_mksnapshot",
":v8_init",
+ ":v8_internal_headers",
":v8_libbase",
":v8_libplatform",
":v8_maybe_icu",
@@ -8655,11 +8699,19 @@ if (is_component_build) {
v8_component("v8") {
sources = [ "src/utils/v8dll-main.cc" ]
- public_deps = [
+ deps = [
":v8_base",
":v8_snapshot",
]
+ public_deps = [
+ ":cppgc_headers",
+ ":v8_abseil",
+ ":v8_headers",
+ ":v8_libplatform",
+ "src/inspector:inspector_headers",
+ ]
+
configs = [ ":internal_config" ]
v8_add_configs += [ "//build/config/compiler:thinlto_optimize_max" ]
v8_remove_configs += [ "//build/config/compiler:thinlto_optimize_default" ]
@@ -8673,11 +8725,14 @@ if (is_component_build) {
sources = [ "src/utils/v8dll-main.cc" ]
public_deps = [
+ ":cppgc_base",
":torque_base",
":torque_ls_base",
":v8_base",
":v8_headers",
+ ":v8_internal_headers",
":v8_snapshot",
+ "src/inspector:inspector_headers",
]
if (v8_enable_turbofan) {
@@ -8691,10 +8746,14 @@ if (is_component_build) {
}
v8_component("cppgc") {
- public_deps = [ ":cppgc_base" ]
+ deps = [ ":cppgc_base" ]
+ public_deps = [
+ ":cppgc_headers",
+ ":v8_libplatform",
+ ]
if (!cppgc_is_standalone) {
- deps = [ ":v8" ]
+ deps += [ ":v8" ]
}
configs = []
@@ -8722,10 +8781,17 @@ if (is_component_build) {
}
} else {
group("v8") {
- public_deps = [
+ deps = [
":v8_base",
":v8_snapshot",
]
+ public_deps = [
+ ":cppgc_headers",
+ ":v8_abseil",
+ ":v8_headers",
+ ":v8_libplatform",
+ "src/inspector:inspector_headers",
+ ]
public_configs = [ ":external_config" ]
}
@@ -8734,10 +8800,14 @@ if (is_component_build) {
testonly = true
public_deps = [
+ ":cppgc_base",
":torque_base",
":torque_ls_base",
":v8_base",
+ ":v8_headers",
+ ":v8_internal_headers",
":v8_snapshot",
+ "src/inspector:inspector_headers",
]
if (v8_enable_turbofan) {
@@ -8749,10 +8819,14 @@ if (is_component_build) {
}
group("cppgc") {
- public_deps = [ ":cppgc_base" ]
+ deps = [ ":cppgc_base" ]
+ public_deps = [
+ ":cppgc_headers",
+ ":v8_libplatform",
+ ]
if (!cppgc_is_standalone) {
- deps = [ ":v8" ]
+ deps += [ ":v8" ]
}
public_configs = [ ":external_config" ]
@@ -8807,6 +8881,7 @@ v8_executable("d8") {
deps = [
":v8",
+ ":v8_internal_headers",
":v8_libbase",
":v8_libplatform",
":v8_simdutf",
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index 67ee185a5af..9547d0667a5 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -99,24 +99,24 @@ vars = {
'chromium_jetstream_git': 'https://chromium.googlesource.com/external/github.com/WebKit/JetStream.git',
# GN CIPD package version.
- 'gn_version': 'git_revision:a99d46a9d04c770d6bb87387058e1d7b151758ce',
+ 'gn_version': 'git_revision:127dd2a6d582528d6d61c4d838dc17385ef31abd',
# ninja CIPD package version
# https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
'ninja_version': 'version:3@1.12.1.chromium.4',
# siso CIPD package version
- 'siso_version': 'git_revision:efbbe7f1892211b5e9512576843a3c247b6a6d7c',
+ 'siso_version': 'git_revision:22353054fea20f637c8fa302a90daf9e2cc10497',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling Fuchsia sdk
# and whatever else without interference from each other.
- 'fuchsia_version': 'version:33.20260824.1.1',
+ 'fuchsia_version': 'version:33.20260915.5.1',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling partition_alloc_version
# and whatever else without interference from each other.
- 'partition_alloc_version': 'c029851c21b7e1154fa3964e08c97710adc92cc7',
+ 'partition_alloc_version': 'a0f30e381c6e132215a0c8d809fd08ff4cdad244',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
@@ -145,11 +145,11 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling agents-internal
# and whatever else without interference from each other.
- 'agents_internal_revision': 'd2d5adf5a243d90aba25902a46fc32e7a4f5ab99',
+ 'agents_internal_revision': '79ff29c61f3fcfd51da0a5be8579b01b4f6f61b3',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling agents-public
# and whatever else without interference from each other.
- 'agents_public_revision': '4e0a8bacdfcc6b6303540aa466b05a508f349486',
+ 'agents_public_revision': '865684c4f7092e4ab05adcd3fcf068672ff28d27',
}
deps = {
@@ -161,9 +161,9 @@ deps = {
'condition': 'checkout_agents_internal',
},
'build':
- Var('chromium_url') + '/chromium/src/build.git' + '@' + '8ca8a372cab9ff143072204053d30fbc2c17bd7a',
+ Var('chromium_url') + '/chromium/src/build.git' + '@' + 'bc0661cf80717e97e1b6868396f61f7f94f2d04a',
'buildtools':
- Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '6f6a5dbf04b734214f3b1f386567d101ec9d607e',
+ Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + 'c202b4a9dac30e789ed6e3b2354efa94357a56f3',
'buildtools/linux64': {
'packages': [
{
@@ -218,7 +218,7 @@ deps = {
'test/mozilla/data':
Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be',
'test/test262/data':
- Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '72faf8ec1445c55149615e8b35187830783aba1a',
+ Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '7ab7fafa0003f73fc85c1b95d88094d33f7eb8bd',
'third_party/android_platform': {
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + 'e3919359f2387399042d31401817db4a02d756ec',
'condition': 'checkout_android',
@@ -260,7 +260,7 @@ deps = {
'dep_type': 'cipd',
},
'third_party/catapult': {
- 'url': Var('chromium_url') + '/catapult.git' + '@' + '50c971fc0958d8c1fb0adcc97f41b90042fa7c87',
+ 'url': Var('chromium_url') + '/catapult.git' + '@' + 'e39ded11ffe971d360160c9d185a7e0ef98fb9a3',
'condition': 'checkout_android',
},
'third_party/clang-format/script':
@@ -278,15 +278,15 @@ deps = {
'condition': 'checkout_android',
},
'third_party/depot_tools':
- Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'cb70c994a656601dc6a0d423f49ff57503bd70bc',
+ Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + '0306e4682b4ac35287c726fa35a983157a625902',
'third_party/dragonbox/src':
Var('chromium_url') + '/external/github.com/jk-jeon/dragonbox.git' + '@' + 'beeeef91cf6fef89a4d4ba5e95d47ca64ccb3a44',
'third_party/fp16/src':
Var('chromium_url') + '/external/github.com/Maratyszcza/FP16.git' + '@' + '782eea126dc5c755827be751a099eb01826175cf',
'third_party/fast_float/src':
- Var('chromium_url') + '/external/github.com/fastfloat/fast_float.git' + '@' + '34164f547b7df3f5d794ff67e9f885c36819ebfc',
+ Var('chromium_url') + '/external/github.com/fastfloat/fast_float.git' + '@' + 'b0ab987b3dfdde13fa1915f65ef2a5c068d9208c',
'third_party/fuchsia-gn-sdk': {
- 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '740d23bfe5b137c2c387a4b421f120f6126845de',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '019c2f57c0f022f63d4d56b4e6427d4f4ea91daa',
'condition': 'checkout_fuchsia',
},
'third_party/simdutf':
@@ -310,15 +310,15 @@ deps = {
'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + '8abf1e701fbd88c8170f48fe0558247e2e5f8e7d',
},
'third_party/fuzztest':
- Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + 'f0f143db954fb311d4e7ba39972d2dab9ba47e2a',
+ Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + '55970ac2863f6b740d3e8247ac0ec48e7acb2113',
'third_party/fuzztest/src':
- Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '846bda6f291e26b7f8fb33c8de23796129bffd12',
+ Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '7a8e9056de2a4f745082a4b3861a67ada47ced36',
'third_party/googletest/src':
Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '4fe3307fb2d9f86d19777c7eb0e4809e9694dde7',
'third_party/highway/src':
Var('chromium_url') + '/external/github.com/google/highway.git' + '@' + '2607d3b5b0113992fe84d3848859eae13b3b52c1',
'third_party/icu':
- Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '6ebb40c594776cc2c21ea14df85a2a89a328b364',
+ Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '5aa526207171ecadf31597f0980a7b7ad8872f33',
'third_party/instrumented_libs': {
'url': Var('chromium_url') + '/chromium/third_party/instrumented_libraries.git' + '@' + 'd15c278eed5d38d9acf2d8054cf37baba93cef8e',
'condition': 'checkout_instrumented_libraries',
@@ -336,178 +336,178 @@ deps = {
'third_party/libc++/src':
Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + '97b436da4c33663581d394f4ee0a5977fc38c2f4',
'third_party/libc++abi/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + 'fc1897a2c12aa27e703c3ed48b62eba8abf4ce19',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + '92767730c5f8350fc53f5b3de5c3c02d00bbab8c',
'third_party/libpfm4':
- Var('chromium_url') + '/chromium/src/third_party/libpfm4.git' + '@' + '4a112befd93f8d90a9b6894b2ec4d320310e1178',
+ Var('chromium_url') + '/chromium/src/third_party/libpfm4.git' + '@' + 'f2fec4fe8bc40a58b1f257e631fc5b8f49b39010',
'third_party/libpfm4/src':
- Var('chromium_url') + '/external/git.code.sf.net/p/perfmon2/libpfm4.git' + '@' + '6870a9f00412830ceaa7e4384bb92ee323e2a28f',
+ Var('chromium_url') + '/external/git.code.sf.net/p/perfmon2/libpfm4.git' + '@' + '9c24ffc9d179244e05584ce4df2f4fbfecdfde9b',
'third_party/libunwind/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '45120ee2331193c3650acc9c427ed267fab31d62',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '24a407d5353ad38f948f107c7d6bc2bcbb4bca24',
'third_party/llvm-libc/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libc.git' + '@' + '43a9a99ce4b5a04954090f8a0e74bf2786f59379',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libc.git' + '@' + '5e61624667bf9e44ea452191dbda0172997018a2',
'third_party/llvm-build/Release+Asserts': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
- 'object_name': 'Linux_x64/clang-android-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '780597375163e78615a307a73ec66346b54c58ea3164aa6fbedf24eae85382fc',
- 'size_bytes': 6210856,
- 'generation': 1787607008868327,
+ 'object_name': 'Linux_x64/clang-android-runtime-library-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'b93725013ccd4f91d5ae40afc1a1b495e07c3be645ddbd7a3b48a7281fcecff8',
+ 'size_bytes': 6208368,
+ 'generation': 1789426565866244,
'condition': 'checkout_android',
},
{
- 'object_name': 'Linux_x64/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '565f7d980b31411e76d9478731cf3f0ac907a46f274d289ea7f03d9137354053',
- 'size_bytes': 56894668,
- 'generation': 1787607001504676,
+ 'object_name': 'Linux_x64/clang-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '8039b5c9e7375df3a8082761cd1220223f90344b81d829c949f69224350d9d47',
+ 'size_bytes': 57238740,
+ 'generation': 1789426559193435,
'condition': 'host_os == "linux"',
},
{
- 'object_name': 'Linux_x64/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '4290664a4fa8aa11fd1e6b2d3ff4965d26b41cca1a4950f9835ff19115c2384f',
- 'size_bytes': 14877500,
- 'generation': 1787607001575317,
+ 'object_name': 'Linux_x64/clang-tidy-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'f8206d1964bd8b59283589ca82159650611e217ad01ab885389f09e177fc80c0',
+ 'size_bytes': 14935260,
+ 'generation': 1789426559088623,
'condition': 'host_os == "linux" and checkout_clang_tidy',
},
{
- 'object_name': 'Linux_x64/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '9db50937915608c466da28ba4166cfa69a5f6bcad346233e47807f532cc3075b',
- 'size_bytes': 15049952,
- 'generation': 1787607001603946,
+ 'object_name': 'Linux_x64/clangd-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '79e4777278ef296219350c6a765eb215e4d23a76c85617ae6b4ec7a7fda524bc',
+ 'size_bytes': 15086928,
+ 'generation': 1789426559098441,
'condition': 'host_os == "linux" and checkout_clangd',
},
{
- 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '34747a8e113c399daa36f75a5a0a4c0963871ceafbce7c49a3b5133f81a63bae',
- 'size_bytes': 2352288,
- 'generation': 1787607001865886,
+ 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'b3b59473f37c63501c00d376c44ea46a59b840dab7298c67ba9101507c48ea65',
+ 'size_bytes': 2371412,
+ 'generation': 1789426559296849,
'condition': 'host_os == "linux" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Linux_x64/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'cc8a621ec8cc3c48471c90cf4ed88dcc56bfb403824eda10f8b55796abaec280',
- 'size_bytes': 5912568,
- 'generation': 1787607001713199,
+ 'object_name': 'Linux_x64/llvmobjdump-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '7da1f3e3754d2b841a909ddbdbdb91cf3cbea3fd7be4b51cbe2cfe171cbfa9d6',
+ 'size_bytes': 5917952,
+ 'generation': 1789426559151920,
'condition': '(checkout_linux or checkout_mac or checkout_android) and host_os == "linux"',
},
{
- 'object_name': 'Mac/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'ba2b707d83f7a19d81b9403b4ebe8e999d41ae35fead00a142f02b67e197fe2f',
- 'size_bytes': 56420628,
- 'generation': 1787607010939621,
+ 'object_name': 'Mac/clang-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '5721c0e801c03b276a9680080ab3d5f0f572945e9d9d683ed8cbd50285598ea0',
+ 'size_bytes': 56731544,
+ 'generation': 1789426567536829,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'da06337f54ba4b36c79e0d379557832bf82b9c7e85fe8ef78a5b953567d98de1',
- 'size_bytes': 1012348,
- 'generation': 1787607018227451,
+ 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '5b7ee53434e68ca2d71a35da8c7bff79e246d5f3d499fddf10e0e3da564d9bdc',
+ 'size_bytes': 980916,
+ 'generation': 1789426574310634,
'condition': 'checkout_mac and not host_os == "mac"',
},
{
- 'object_name': 'Mac/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'ae5cbec1362517b6928162fddb9b160bd1c75e8fd90789718393e1cadf1342ae',
- 'size_bytes': 14882308,
- 'generation': 1787607010909866,
+ 'object_name': 'Mac/clang-tidy-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '5aee98783a53c1acb489f78767c3562818759ee73ded863d08f9645233a3692e',
+ 'size_bytes': 14948968,
+ 'generation': 1789426567538151,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_tidy',
},
{
- 'object_name': 'Mac/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '73f5de0f007f8c588593d824147963ec770b66d487a707d1c377a06e34952d89',
- 'size_bytes': 16779464,
- 'generation': 1787607010899287,
+ 'object_name': 'Mac/clangd-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '74451b27944643780298bf5b667d41c2bc026f9fabbaaa543bd6a569d7cf3181',
+ 'size_bytes': 16825280,
+ 'generation': 1789426567538026,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clangd',
},
{
- 'object_name': 'Mac/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'c47eb37873d3290cc95ba5f9027337895eeeaa199c3f70e63c5d09b710faf250',
- 'size_bytes': 2411184,
- 'generation': 1787607011184644,
+ 'object_name': 'Mac/llvm-code-coverage-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '25fcd6877fd1124a879650c5d828ab9aac6a89bbb679188de89875656c062836',
+ 'size_bytes': 2423848,
+ 'generation': 1789426567755049,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Mac/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '4ddefa96f6aaa04ac502610fc736528f65dc3e1b997fc4a5380081937f6ffb1a',
- 'size_bytes': 5874672,
- 'generation': 1787607011035157,
+ 'object_name': 'Mac/llvmobjdump-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'fddb9d463c7c86698711435c1cab0e3dfd039ca6716ba5faed765e215ace9472',
+ 'size_bytes': 5908332,
+ 'generation': 1789426567556141,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac_arm64/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '264d803970f9b58ddbdc90464ad82e54cef642c58ec371ba5356dfa7342ece4d',
- 'size_bytes': 47226204,
- 'generation': 1787607020088085,
+ 'object_name': 'Mac_arm64/clang-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'c6519a944e9ddd34fcc5273cdf1997f674c6d929b70eecd9020646774aa7b8aa',
+ 'size_bytes': 47559168,
+ 'generation': 1789426576079342,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Mac_arm64/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '3e02eae391e05018fb4e95d3c90b270688a5e3d5f5b31df6c59512e602478f36',
- 'size_bytes': 12960456,
- 'generation': 1787607020070956,
+ 'object_name': 'Mac_arm64/clang-tidy-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '6858c97a00a3e89de7b4bc1f4d2ed608811994067a5a8749ba830e39d10c456a',
+ 'size_bytes': 12998944,
+ 'generation': 1789426576095992,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_tidy',
},
{
- 'object_name': 'Mac_arm64/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'a56514d09cfcb216efa297e5fecd51a2e248faf7db6edd2d444cfe78e0e219d3',
- 'size_bytes': 13320572,
- 'generation': 1787607020209265,
+ 'object_name': 'Mac_arm64/clangd-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'e8898cbd3448cea483971f8bd72fc3f45e59d5f02c639ce674c08b484cb42a1b',
+ 'size_bytes': 13313524,
+ 'generation': 1789426576068075,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clangd',
},
{
- 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'b593c509e8f4269cf4a16272f6eddcea0f9dd47f6f3fe39b9813041d0f96d4e3',
- 'size_bytes': 2031112,
- 'generation': 1787607020489366,
+ 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'ce7a2040d2321222ae5751f0ecc3a8abf21da81f532095497524eb462ade02ff',
+ 'size_bytes': 2043608,
+ 'generation': 1789426576226450,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Mac_arm64/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': 'c67f5dba316d6367be8c153ede456fdbef0dfffad4da10aaf597ff967c07378c',
- 'size_bytes': 5610096,
- 'generation': 1787607020228775,
+ 'object_name': 'Mac_arm64/llvmobjdump-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '53bd87b22289bd2df2e05a0f6a1bd297c8d8fc636584562668c72fee224354e6',
+ 'size_bytes': 5645448,
+ 'generation': 1789426576105416,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Win/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '166437ede456b3d7cf0d9317287511e47714f91da547dbde02992261aeef7174',
- 'size_bytes': 51467544,
- 'generation': 1787607030157700,
+ 'object_name': 'Win/clang-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'fcb789024398956d51b9b6018230b84981fe9160158c0de68e3ca4f254504cf3',
+ 'size_bytes': 51838392,
+ 'generation': 1789426584693424,
'condition': 'host_os == "win"',
},
{
- 'object_name': 'Win/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '13cae70dfa207c9ec27e294f38b732b5c820ef637f48d24cc8b97f5f3a96e220',
- 'size_bytes': 15134360,
- 'generation': 1787607030186388,
+ 'object_name': 'Win/clang-tidy-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'e9c2f8b25cf6c2cc024c23823fbfb0d19149ab08faaec3bdb67e525eb224b20d',
+ 'size_bytes': 15129656,
+ 'generation': 1789426584789667,
'condition': 'host_os == "win" and checkout_clang_tidy',
},
{
- 'object_name': 'Win/clang-win-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '4ff9a06f5fc4a711103cd890e724ae4448d67873de438542f3ac6772e68d3c63',
- 'size_bytes': 2638196,
- 'generation': 1787607037249082,
+ 'object_name': 'Win/clang-win-runtime-library-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': '0556e0ba5ca0ecabdf16b544d3b671994f719a9b8530b77c9474ed5922d37f2b',
+ 'size_bytes': 2650852,
+ 'generation': 1789426591392711,
'condition': 'checkout_win and not host_os == "win"',
},
{
- 'object_name': 'Win/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '17f1d575127724051099a778d77e609f650702248cf4e7ff3ec33b377053edd9',
- 'size_bytes': 15444040,
- 'generation': 1787607030301504,
+ 'object_name': 'Win/clangd-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'c8cf60febcf4e7fcba61ab32153ea089d2b49ebe7d8d05230eb0c1ddc6d449f6',
+ 'size_bytes': 15433972,
+ 'generation': 1789426584780463,
'condition': 'host_os == "win" and checkout_clangd',
},
{
- 'object_name': 'Win/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '78aa6b2b9cf057077be6705b76e43ffed83e46e17ee86da1ab699340129b1aca',
- 'size_bytes': 2512968,
- 'generation': 1787607030493491,
+ 'object_name': 'Win/llvm-code-coverage-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'fe05d04734b47fd6e88602e597cab43a3f37eaa3f6f2e44f2ba808af8378a7b5',
+ 'size_bytes': 2527212,
+ 'generation': 1789426585050946,
'condition': 'host_os == "win" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Win/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
- 'sha256sum': '4b899193da883a447c75f057e3a94f5e7ab93e5df5724ad94cbd6bf82ea792b4',
- 'size_bytes': 5994644,
- 'generation': 1787607030276791,
+ 'object_name': 'Win/llvmobjdump-llvmorg-24-init-7747-g62397f8b-29.tar.xz',
+ 'sha256sum': 'afb8027a34fd80557a3c500a3f77e1b0aa0c2f93c9c51becddd9dddbc555936e',
+ 'size_bytes': 6016140,
+ 'generation': 1789426584846994,
'condition': '(checkout_linux or checkout_mac or checkout_android) and host_os == "win"',
},
],
@@ -531,9 +531,9 @@ deps = {
'condition': 'not build_with_chromium',
},
'third_party/perfetto':
- Var('chromium_url') + '/external/github.com/google/perfetto.git' + '@' + '5dbeaad4ceb91470a835426b52e0cb43a3e5ef10',
+ Var('chromium_url') + '/external/github.com/google/perfetto.git' + '@' + 'aac4c25edfa1ad236f61622959166bc180a8ad2b',
'third_party/protobuf':
- Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + '5f8c379d1fc89fe8eee16ae560dd5e514a4608da',
+ Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + '398c57e93a383373546bc6ae5ac2052b6155f2ba',
'third_party/re2/src':
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + '972a15cedd008d846f1a39b2e88ce48d7f166cbd',
'third_party/requests': {
@@ -541,41 +541,41 @@ deps = {
'condition': 'checkout_android',
},
'tools/rust':
- Var('chromium_url') + '/chromium/src/tools/rust' + '@' + '54d1148695dbbbfc3e00dfd05aff502acaa602e3',
+ Var('chromium_url') + '/chromium/src/tools/rust' + '@' + '187bdac7c732777cf5e1b82b9caf6034d3a7e4e5',
'tools/win':
Var('chromium_url') + '/chromium/src/tools/win' + '@' + '13cb6e5d223dc49eadd082d3aef4c2a5b0e4c0a0',
'third_party/rust':
- Var('chromium_url') + '/chromium/src/third_party/rust' + '@' + '4dec6f65bcb34c4c289736b0e6fd571b35c6c665',
+ Var('chromium_url') + '/chromium/src/third_party/rust' + '@' + '4be2b73f368c8c2a3f5a42c16459b80d7d81b318',
'third_party/rust-toolchain': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
- 'object_name': 'Linux_x64/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '4b131e81d157a97bcf454ad0fbb71bc2063b2a3708c858410c04201ef06134e5',
- 'size_bytes': 276314860,
- 'generation': 1786821088882867,
+ 'object_name': 'Linux_x64/rust-toolchain-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '5a56edc35db24efbbe0373c724457c31a1febd75cbef6ac7fc9a1c5bca6fc697',
+ 'size_bytes': 276524576,
+ 'generation': 1789143384016025,
'condition': 'host_os == "linux"',
},
{
- 'object_name': 'Mac/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '12ca849195c27495073ba52ae7126d8a4a9a5807cd7a0dc6ba6b6fa612302a6d',
- 'size_bytes': 264031896,
- 'generation': 1786821092536805,
+ 'object_name': 'Mac/rust-toolchain-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '62530251d7e7d3741840289a45a3e4950ad0023857e03bf0e9d57f2d723a8624',
+ 'size_bytes': 264337576,
+ 'generation': 1789143387895737,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac_arm64/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': 'fe128475561d7a51c797d1cb3ccea6f94fd770b167c8e0cc33bf75e7c25d8225',
- 'size_bytes': 248465344,
- 'generation': 1786821096222521,
+ 'object_name': 'Mac_arm64/rust-toolchain-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '5db21ffd4909ce82c0832df9d1eb06b01b15a54176b7341e39f7181f4b483dbc',
+ 'size_bytes': 248304876,
+ 'generation': 1789143391575553,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Win/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '14bc9cea5e00cb191f58204ef44d68a6794f856a76f885c50298a12d052035bc',
- 'size_bytes': 414479372,
- 'generation': 1786821099612317,
+ 'object_name': 'Win/rust-toolchain-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '487387d6c7cfec69b06d613eb0f68331a3b56b1081f73bc673a1b26299865379',
+ 'size_bytes': 416611108,
+ 'generation': 1789143395284107,
'condition': 'host_os == "win"',
},
],
@@ -594,31 +594,31 @@ deps = {
'bucket': 'chromium-browser-clang',
'objects': [
{
- 'object_name': 'Linux_x64/rust-libclang-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': 'a36afcfb09b2b096cd7d17b6008beb1993c3962d780a7ccc0aa4c5f544447429',
- 'size_bytes': 22734560,
- 'generation': 1786821090667672,
+ 'object_name': 'Linux_x64/rust-libclang-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '59c2086dabf6494fb7cc4690910d4dfddd9a598a1ecaf19d8408197445bbf7c3',
+ 'size_bytes': 22899948,
+ 'generation': 1789143385954506,
'condition': 'host_os == "linux"',
},
{
- 'object_name': 'Mac/rust-libclang-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '0ff3d2a46a0ed3851311cce6aa60f70f3d3e88e4177c2b10806c990a72461f67',
- 'size_bytes': 23130796,
- 'generation': 1786821094366500,
+ 'object_name': 'Mac/rust-libclang-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': '6fa15d9cf2ff55b5ae1e4276369cfbde1f4f770e60ccb133e1fc7446c5ce607e',
+ 'size_bytes': 23309500,
+ 'generation': 1789143389794597,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac_arm64/rust-libclang-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '0a95d15ec7e992b60f47b9cf98f951b32f718488aa5d15d1c8cbae81f1db6b39',
- 'size_bytes': 20545284,
- 'generation': 1786821097847085,
+ 'object_name': 'Mac_arm64/rust-libclang-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': 'd330fd41100be52b4e804c9252b3f3bb34cfed16d2973934de0930b297f7201e',
+ 'size_bytes': 20689276,
+ 'generation': 1789143393459608,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Win/rust-libclang-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
- 'sha256sum': '75033b0243acf7c25227f6015c60797724b98d1de5514e9e1a374735ef76aa4e',
- 'size_bytes': 21534908,
- 'generation': 1786821101319840,
+ 'object_name': 'Win/rust-libclang-1edd55dcfcd573872c727fa3e086369a71661ee0-2-llvmorg-24-init-7747-g62397f8b.tar.xz',
+ 'sha256sum': 'fbe9978289a35ca45da1c1393ed6ef8adc86907d36a4ce81fcf590f56b07a096',
+ 'size_bytes': 21677148,
+ 'generation': 1789143397092006,
'condition': 'host_os == "win"',
},
],
@@ -656,20 +656,20 @@ deps = {
'dep_type': 'cipd',
},
'third_party/zlib':
- Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '285e94b8fa95ad3b7d16b80798ec8dce6febb8c8',
+ Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '13395eebe853e811d274f7bd9b71fb7d9b5a5851',
'tools/clang':
- Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '450d823868eaee61e2b2cb986e19aec287f16d58',
+ Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '10f700407ca356594ea2a575572b7ce63183721d',
'tools/protoc_wrapper':
Var('chromium_url') + '/chromium/src/tools/protoc_wrapper.git' + '@' + 'e9dbe1bf6a2a5d2d4973725874259eed587cf18d',
'third_party/abseil-cpp': {
- 'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + '435e7d977fb36fb47854a4c552c0706dad0bd7cf',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + 'edf0931ff4e2cddfeecade307ae948b5d09b8b38',
'condition': 'not build_with_chromium',
},
'third_party/fadec/src': {
'url': Var('chromium_url') + '/external/github.com/aengelke/fadec.git' + '@' + 'c9f78f532b9004de278489019ab2c6c28ae9746e',
},
'third_party/disarm/src': {
- 'url': Var('chromium_url') + '/external/github.com/aengelke/disarm.git' + '@' + '2d13d3f410a52daff1c5d8ef07d623332f372560',
+ 'url': Var('chromium_url') + '/external/github.com/aengelke/disarm.git' + '@' + '2d960dae4b4fb29dba05cfc48210fbed423f3d2c',
},
'third_party/zoslib': {
'url': Var('chromium_url') + '/external/github.com/ibmruntimes/zoslib.git' + '@' + '804b13554e8dd6972a591c1d6e532514fadd42a8',
diff --git a/deps/v8/PRESUBMIT.py b/deps/v8/PRESUBMIT.py
index 335f2333e0b..1bbf577c86d 100644
--- a/deps/v8/PRESUBMIT.py
+++ b/deps/v8/PRESUBMIT.py
@@ -848,19 +848,23 @@ def _CheckNoexceptAnnotations(input_api, output_api):
def _CheckMetagenHeaders(input_api, output_api):
- """Check that tools/metagen's driver still reaches every heap object.
+ """Check that src/objects/all-objects.h includes every heap object header.
tools/metagen/metagen.py harvests the InstanceType enum from the class
- declarations its driver's include closure reaches. A header that grows a
- V8_OBJECT / V8_IT_ class but that nothing in the closure includes is
- silently skipped -- the class simply gets no instance type -- so catch the
- drift at upload time.
-
- Reachability is resolved textually rather than by preprocessing, and
- conditional includes are followed regardless of their guard: a header
- reachable only under V8_INTL_SUPPORT still counts as reached, because the
- harvest runs per build configuration and sees it in the configs that
- enable it.
+ declarations included by all-objects.h. A header with a V8_OBJECT /
+ V8_IT_ class that all-objects.h does not include is skipped without
+ error and its class gets no instance type, so check at upload time.
+
+ The check requires direct inclusion because BUILD.gn declares only
+ all-objects.h as an input of the harvest. A header included through an
+ intermediate header is still harvested, but the intermediate is in
+ neither the action's inputs nor the depfile, so an incremental build
+ keeps a stale instance-types.h.
+
+ Includes are read textually, not by preprocessing, and conditional ones
+ count regardless of their guard: the harvest runs per build
+ configuration, so a header included only under V8_INTL_SUPPORT is
+ harvested in the configurations that enable it.
"""
import subprocess
v8_root = input_api.PresubmitLocalPath()
@@ -890,35 +894,28 @@ def _CheckMetagenHeaders(input_api, output_api):
]
live = set(res.stdout.split())
- include_re = re.compile(r'^\s*#\s*include\s+"([^"]+)"', re.MULTILINE)
- driver = join("tools", "metagen", "harvest-driver.cc")
- reached = set()
- queue = [driver]
- while queue:
- rel = queue.pop()
- if rel in reached:
- continue
- reached.add(rel)
- try:
- with open(join(v8_root, rel)) as f:
- body = f.read()
- except OSError:
- # Not a V8 file (a system or third_party header); its includes
- # cannot reach a V8_OBJECT declaration we care about.
- continue
- queue.extend(include_re.findall(body))
+ aggregate = join("src", "objects", "all-objects.h")
+ try:
+ with open(join(v8_root, aggregate)) as f:
+ body = f.read()
+ except OSError as e:
+ return [
+ output_api.PresubmitNotifyResult(
+ f"_CheckMetagenHeaders: skipping ({aggregate}: {e})")
+ ]
+ included = set(re.findall(r'^\s*#\s*include\s+"([^"]+)"', body, re.MULTILINE))
- missing = sorted(live - reached)
+ missing = sorted(live - included)
if not missing:
return []
return [
output_api.PresubmitError("\n".join([
- f"{driver} no longer reaches every heap object.",
- "These headers carry a V8_OBJECT/V8_IT_ marker but nothing in the "
- "driver's include closure includes them, so metagen assigns their "
- "classes no instance type:",
+ f"{aggregate} no longer includes every heap object header.",
+ "These headers carry a V8_OBJECT/V8_IT_ marker but are not "
+ "included there, so metagen either misses their classes or "
+ "harvests them through a header the build does not depend on:",
] + [f" {h}" for h in missing] + [
- "Add them to src/objects/all-objects.h.",
+ f"Add them to {aggregate}.",
]))
]
diff --git a/deps/v8/agents/.vpython3 b/deps/v8/agents/.vpython3
deleted file mode 100644
index 9a55b6ba5af..00000000000
--- a/deps/v8/agents/.vpython3
+++ /dev/null
@@ -1,137 +0,0 @@
-python_version: "3.11"
-
-wheel: <
- name: "infra/python/wheels/pyyaml/${vpython_platform}"
- version: "version:5.4.1.chromium.1"
->
-
-wheel: <
- name: "infra/python/wheels/tabulate-py3"
- version: "version:0.9.0"
->
-
-wheel: <
- name: "infra/python/wheels/platformdirs-py3"
- version: "version:4.9.2"
->
-
-wheel: <
- name: "infra/python/wheels/mcp-py3"
- version: "version:1.9.4"
->
-wheel: <
- name: "infra/python/wheels/pydantic-py3"
- version: "version:2.11.7"
->
-wheel: <
- name: "infra/python/wheels/starlette-py3"
- version: "version:0.47.1"
->
-wheel: <
- name: "infra/python/wheels/anyio-py3"
- version: "version:4.9.0"
->
-wheel: <
- name: "infra/python/wheels/sniffio-py3"
- version: "version:1.3.0"
->
-wheel: <
- name: "infra/python/wheels/idna-py3"
- version: "version:3.4"
->
-wheel: <
- name: "infra/python/wheels/typing-extensions-py3"
- version: "version:4.13.2"
->
-wheel: <
- name: "infra/python/wheels/httpx_sse-py3"
- version: "version:0.4.1"
->
-wheel: <
- name: "infra/python/wheels/httpx-py3"
- version: "version:0.28.1"
->
-wheel: <
- name: "infra/python/wheels/certifi-py3"
- version: "version:2025.4.26"
->
-wheel: <
- name: "infra/python/wheels/httpcore-py3"
- version: "version:1.0.9"
->
-wheel: <
- name: "infra/python/wheels/h11-py3"
- version: "version:0.16.0"
->
-wheel: <
- name: "infra/python/wheels/pydantic-settings-py3"
- version: "version:2.10.1"
->
-wheel: <
- name: "infra/python/wheels/python-multipart-py3"
- version: "version:0.0.20"
->
-wheel: <
- name: "infra/python/wheels/sse-starlette-py3"
- version: "version:2.4.1"
->
-wheel: <
- name: "infra/python/wheels/uvicorn-py3"
- version: "version:0.35.0"
->
-wheel: <
- name: "infra/python/wheels/annotated-types-py3"
- version: "version:0.7.0"
->
-wheel: <
- name: "infra/python/wheels/pydantic_core/${vpython_platform}"
- version: "version:2.33.2"
->
-wheel: <
- name: "infra/python/wheels/typing-inspection-py3"
- version: "version:0.4.1"
->
-wheel: <
- name: "infra/python/wheels/python-dotenv-py3"
- version: "version:1.1.1"
->
-wheel: <
- name: "infra/python/wheels/click-py3"
- version: "version:8.0.3"
->
-wheel: <
- name: "infra/python/wheels/colorama-py2_py3"
- version: "version:0.4.1"
->
-wheel: <
- name: "infra/python/wheels/perfetto-py3"
- version: "version:0.16.0"
->
-wheel: <
- name: "infra/python/wheels/protobuf-py3"
- version: "version:6.33.5"
->
-wheel: <
- name: "infra/python/wheels/pandas/${vpython_platform}"
- version: "version:2.2.3.chromium.1"
->
-wheel: <
- name: "infra/python/wheels/numpy/${vpython_platform}"
- version: "version:1.23.5.chromium.4"
->
-wheel: <
- name: "infra/python/wheels/python-dateutil-py2_py3"
- version: "version:2.9.0"
->
-wheel: <
- name: "infra/python/wheels/pytz-py2_py3"
- version: "version:2025.2"
->
-wheel: <
- name: "infra/python/wheels/six-py2_py3"
- version: "version:1.17.0"
->
-wheel: <
- name: "infra/python/wheels/tzdata-py2_py3"
- version: "version:2025.2"
->
diff --git a/deps/v8/agents/README.md b/deps/v8/agents/README.md
index 2d4e4f31732..aeb73ceffc3 100644
--- a/deps/v8/agents/README.md
+++ b/deps/v8/agents/README.md
@@ -1,7 +1,7 @@
# V8 Coding Agents
This directory provides a centralized location for files related to AI coding
-agents (e.g. `gemini-cli`) used for development within V8.
+agents (e.g. `jetski-cli`) used for development within V8.
The goal is to provide a scalable and organized way to share prompts and tools
among developers, accommodating the various environments (Linux, Mac, Windows)
@@ -14,18 +14,15 @@ in
## Directory Structure
-### Subagents
+### Skills & Rules
-On-demand expertise for specific tasks. Source files are located in
-[`agents/`](agents/).
+Reusable workflows, commands, and conventions live in `skills/` and `rules/`.
-To use them, you need to run the appropriate installation script from the
-`agents/` directory:
+To install them for your agent environment, run the appropriate installation
+script from the `agents/` directory:
-- **For Gemini CLI**: Run `vpython3 scripts/install_for_gemini_cli.py` to
- generate the subagent files in `.gemini/agents/`.
- **For Jetski**: Run `vpython3 scripts/install_for_jetski.py` to create
- symlinks in `.agents/agents/`.
+ symlinks in `.agents/`.
- **For GitHub Copilot CLI**: Run `vpython3 scripts/install_for_copilot_cli.py`
to generate repository instructions in `.github/copilot-instructions.md`,
install compatible V8 rules as instruction files in `.github/instructions/`,
diff --git a/deps/v8/agents/agents/builder/agent.json b/deps/v8/agents/agents/builder/agent.json
deleted file mode 100644
index 76a25ad8b64..00000000000
--- a/deps/v8/agents/agents/builder/agent.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "builder",
- "description": "Specializes in building V8.",
- "config_path": "config.yaml"
-}
\ No newline at end of file
diff --git a/deps/v8/agents/agents/builder/config.yaml b/deps/v8/agents/agents/builder/config.yaml
deleted file mode 100644
index 7d1a87f4700..00000000000
--- a/deps/v8/agents/agents/builder/config.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-custom_agent:
- system_prompt_sections:
- - content: |-
- You are a build assistant. Your goal is to compile V8 for specified configurations. You can read files and search code to understand build errors.
- title: Instructions
- tool_names:
- - run_command
- - view_file
- - grep_search
- - list_dir
- - mcp_*
diff --git a/deps/v8/agents/agents/debugger/agent.json b/deps/v8/agents/agents/debugger/agent.json
deleted file mode 100644
index 2cd61be6d6b..00000000000
--- a/deps/v8/agents/agents/debugger/agent.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "debugger",
- "description": "Specializes in interactive debugging and crash analysis.",
- "config_path": "config.yaml"
-}
\ No newline at end of file
diff --git a/deps/v8/agents/agents/debugger/config.yaml b/deps/v8/agents/agents/debugger/config.yaml
deleted file mode 100644
index d5ab65ee34f..00000000000
--- a/deps/v8/agents/agents/debugger/config.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-custom_agent:
- system_prompt_sections:
- - content: |-
- You are a debugging assistant. Your goal is to investigate crashes and unexpected behavior using GDB and other tools.
- title: Instructions
- tool_names:
- - run_command
- - view_file
- - grep_search
- - list_dir
- - call_mcp_tool
- - mcp_*
diff --git a/deps/v8/agents/agents/researcher/agent.json b/deps/v8/agents/agents/researcher/agent.json
deleted file mode 100644
index 933c9a9ab38..00000000000
--- a/deps/v8/agents/agents/researcher/agent.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "researcher",
- "description": "Specializes in exploring the codebase and finding information.",
- "config_path": "config.yaml"
-}
\ No newline at end of file
diff --git a/deps/v8/agents/agents/researcher/config.yaml b/deps/v8/agents/agents/researcher/config.yaml
deleted file mode 100644
index 8d5d84529bb..00000000000
--- a/deps/v8/agents/agents/researcher/config.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-custom_agent:
- system_prompt_sections:
- - content: |-
- You are a research assistant. Your goal is to find relevant code, documentation, and information in the V8 codebase and the web. You provide detailed reports with file paths and line numbers.
- title: Instructions
- tool_names:
- - view_file
- - grep_search
- - list_dir
- - search_web
- - mcp_*
diff --git a/deps/v8/agents/agents/tester/agent.json b/deps/v8/agents/agents/tester/agent.json
deleted file mode 100644
index bc7feb78cba..00000000000
--- a/deps/v8/agents/agents/tester/agent.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "tester",
- "description": "Specializes in running tests and benchmarks.",
- "config_path": "config.yaml"
-}
\ No newline at end of file
diff --git a/deps/v8/agents/agents/tester/config.yaml b/deps/v8/agents/agents/tester/config.yaml
deleted file mode 100644
index de6f45cf019..00000000000
--- a/deps/v8/agents/agents/tester/config.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-custom_agent:
- system_prompt_sections:
- - content: |-
- You are a test assistant. Your goal is to run tests and benchmarks and report results. You can read files and search code to understand test failures.
- title: Instructions
- tool_names:
- - run_command
- - view_file
- - grep_search
- - list_dir
- - mcp_*
diff --git a/deps/v8/agents/plugins/install.py b/deps/v8/agents/plugins/install.py
index 160c25f6334..4c18a73eb3f 100755
--- a/deps/v8/agents/plugins/install.py
+++ b/deps/v8/agents/plugins/install.py
@@ -38,7 +38,7 @@ class AgentPlatform:
mcp_config: dict
def _load_config(self) -> dict:
- if self.config_path.exists():
+ if not self.config_path.exists():
return {"mcpServers": {}}
cfg = load_json(self.config_path)
if "mcpServers" not in cfg:
@@ -109,43 +109,15 @@ class CliAgentPlatform(AgentPlatform):
pass
-class GeminiPlatform(CliAgentPlatform):
- """Implementation for Gemini CLI MCP configuration."""
+class JetskiPlatform(AgentPlatform):
+ """Implementation for Jetski MCP configuration."""
- NAME = "gemini"
- BINARY = "gemini"
- COMMAND: ClassVar[str] = "mcp"
- EXTRA_ARGS: ClassVar[list[str]] = ["--scope", "user"]
+ NAME = "jetski"
def __init__(self) -> None:
- super().__init__()
self.config_path = Path.home() / ".gemini/config/mcp_config.json"
self.mcp_config = self._load_config()
- def _remove_server_cli(self, server_name: str) -> bool:
- cmd = [self.BINARY, self.COMMAND, "remove", server_name] + self.EXTRA_ARGS
- res = self._run(cmd, check=False)
- return res.returncode == 0
-
- def register_server(self, server_name: str, server_info: dict) -> dict:
- config = super().register_server(server_name, server_info)
- self._remove_server_cli(server_name)
- cmd = [self.BINARY, self.COMMAND, "add"] + self.EXTRA_ARGS
- for k, v in config.get("env", {}).items():
- cmd.extend(["-e", f"{k}={v}"])
- cmd.extend([server_name, config["command"]] + config["args"])
- self._run(cmd, check=True)
- return config
-
-
-class JetskiPlatform(GeminiPlatform):
- """Implementation for Jetski MCP configuration."""
-
- NAME = "jetski"
- BINARY = "jetski-cli"
- COMMAND = "plugin"
- EXTRA_ARGS = []
-
class ClaudeDesktopPlatform(AgentPlatform):
"""Implementation for Claude Desktop MCP configuration.
@@ -200,7 +172,6 @@ class ClaudeCLIPlatform(CliAgentPlatform):
AGENT_PLATFORMS: Final[list[type[AgentPlatform]]] = [
- GeminiPlatform,
JetskiPlatform,
ClaudeDesktopPlatform,
ClaudeCLIPlatform,
@@ -216,13 +187,17 @@ def get_platform(agent_name: str) -> AgentPlatform:
def get_available_plugins() -> dict[str, dict]:
- """Scans agents/plugins for available Gemini plugins."""
- # TODO: support other agent directories too.
+ """Scans agents/plugins for available agent plugins."""
plugins = {}
plugins_dir = _PROJECT_ROOT / "agents/plugins"
- for manifest_path in plugins_dir.glob("*/gemini-extension.json"):
+ for manifest_path in plugins_dir.glob("*/plugin.json"):
plugin_name = manifest_path.parent.name
manifest = load_json(manifest_path)
+ mcp_config_path = manifest_path.parent / "mcp_config.json"
+ if mcp_config_path.exists():
+ mcp_config = load_json(mcp_config_path)
+ manifest.setdefault("mcpServers",
+ {}).update(mcp_config.get("mcpServers", {}))
plugins[plugin_name] = {
"manifest_path": manifest_path,
"manifest": manifest,
@@ -335,7 +310,7 @@ def main() -> None:
)
remove_parser = subparsers.add_parser(
- "remove", help="Remove plugins from target agent.")
+ "remove", aliases=["rm"], help="Remove plugins from target agent.")
remove_parser.add_argument(
"plugins", nargs="+", help="Plugin names to remove.")
diff --git a/deps/v8/agents/prompts/README.md b/deps/v8/agents/prompts/README.md
index 0d78352ca59..1826e0796ab 100644
--- a/deps/v8/agents/prompts/README.md
+++ b/deps/v8/agents/prompts/README.md
@@ -1,28 +1,15 @@
# Prompts
-This directory contains the common prompt for V8 and template prompts to teach
-agents about specific tools. Everything is intended to work with gemini-cli.
+This directory contains the system instruction prompt template
+(`templates/modular.md`) for V8 coding agents (`jetski-cli`).
## Creating the System Instruction Prompt
-Create a local, untracked `GEMINI.md` file in your root directory. Include
-relevant prompts using the `@` syntax. For example:
-
-```GEMINI.md
-@agents/prompts/common.md
-```
-
-You can confirm that prompts were successfully imported by running the
-`/memory show` command in gemini-cli.
-
-## Known problems
-
-All imports must be scoped to the current prompt file. a/prompt.md can import
-a/prompt2.md or a/b/prompt3.md, but cannot import c/prompt4.md. See
-https://github.com/google-gemini/gemini-cli/issues/4098.
+Run `vpython3 agents/scripts/install_for_jetski.py` to generate your root
+`GEMINI.md` file from `agents/prompts/templates/modular.md` and link `.agents/`
+rules and skills.
## Contributing
-Changes to `common.md` should be done *carefully* as it's meant to be used
-broadly. Use the `template/` directory to add new prompts that you want to
-share.
+Changes to `templates/modular.md` should be done *carefully* as it is meant to
+be used broadly across V8 workspaces.
diff --git a/deps/v8/agents/prompts/common.md b/deps/v8/agents/prompts/common.md
deleted file mode 100644
index da65c3406c2..00000000000
--- a/deps/v8/agents/prompts/common.md
+++ /dev/null
@@ -1,268 +0,0 @@
-# Gemini Workspace for V8
-
-This is the workspace configuration for V8 when using Gemini.
-
-Documentation can be found at https://v8.dev/docs.
-
-## Key Commands
-
-- **Build (Debug):** `tools/dev/gm.py quiet x64.debug tests`
-- **Build (Optimized Debug):** `tools/dev/gm.py quiet x64.optdebug tests`
-- **Build (Release):** `tools/dev/gm.py quiet x64.release tests`
-- **Run All Tests:**
- `tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug`
-- **Run C++ Tests:**
- `tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug cctest unittests`
-- **Run JavaScript Tests:**
- `tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug mjsunit`
-- **Format Code:** `git cl format`
-
-Some hints:
-
-- You are an expert C++ developer.
-- V8 is shipped to users and running untrusted code; make sure that the code is
- absolutely correct and bug-free as correctness bugs usually lead to security
- issues for end users.
-- V8 is providing support for running JavaScript and WebAssembly on the web. As
- such, it is critical to aim for best possible performance when optimizing V8.
-
-## Folder structure
-
-- `src/`: The main source folder providing the implementation of the virtual
- machine. Key subdirectories include:
- - `src/api/`: Implements the V8 public C++ API, as declared in `include/`.
- - `src/ast/`: Defines the Abstract Syntax Tree (AST) used to represent parsed
- JavaScript, including nodes, scopes, and variables.
- - `src/base/`: Provides fundamental, low-level utilities, data structures, and
- a platform abstraction layer for the entire V8 project.
- - `src/baseline/`: Implements the Sparkplug baseline compiler, which generates
- machine code directly from bytecode for a fast performance boost.
- - `src/bigint/`: The implementation of BigInt operations.
- - `src/builtins/`: Implementation of JavaScript built-in functions (e.g.,
- `Array.prototype.map`).
- - `src/codegen/`: Code generation, including direct machine code generation
- via macro assemblers, higher level codegen via CodeStubAssembler,
- definitions of machine code metadata like safepoint tables and source
- position tables, and `compiler.cc` which defines entry points into the
- compilers. This contains subdirectories for architecture specific
- implementations, which should be kept in sync with each other as much as
- possible.
- - `src/common/`: Common definitions and utilities.
- - `src/compiler/`: The TurboFan optimizing compiler, including the Turboshaft
- CFG compiler.
- - `src/d8/`: The `d8` shell implementation, for running V8 in a CLI.
- - `src/debug/`: The debugger and debug protocol implementation.
- - `src/deoptimizer/`: The deoptimizer implementation, which translates
- optimized frames into unoptimized ones.
- - `src/execution/`: The definitions of the execution environment, including
- the Isolate, frame definitions, microtasks, stack guards, tiering, and
- on-stack argument handling.
- - `src/handles/`: The handle implementation for GC-safe object references.
- - `src/heap/`: The garbage collector and memory management code.
- - `src/ic/`: The Inline Caching implementation.
- - `src/init/`: The V8 initialization code.
- - `src/inspector/`: The inspector protocol implementation.
- - `src/interpreter/`: The Ignition bytecode compiler and interpreter.
- - `src/json/`: The JSON parser and serializer.
- - `src/libplatform/`: The platform abstraction layer, for task runners and
- worker threads.
- - `src/logging/`: The logging implementation.
- - `src/maglev/`: The Maglev mid-tier optimizing compiler.
- - `src/numbers/`: Implementations of various numeric operations.
- - `src/objects/`: The representation and behaviour of V8 internal and
- JavaScript objects.
- - `src/parsing/`: The parser and scanner implementation.
- - `src/profiler/`: The in-process profiler implementations, for heap
- snapshots, allocation tracking, and a sampling CPU profiler.
- - `src/regexp/`: The regular expression implementation. This contains
- subdirectories for architecture specific implementations, which should be
- kept in sync with each other as much as possible.
- - `src/runtime/`: C++ functions that can be called from JavaScript at runtime.
- - `src/sandbox/`: The implementation of the sandbox, which is a security
- feature that attempts to limit V8 memory operations to be within a single
- guarded virtual memory allocation, such that corruptions of objects within
- the sandbox cannot lead to corruption of objects outside of it.
- - `src/snapshot/`: The snapshot implementation, for both the startup snapshot
- (read-only, startup heap, and startup context), as well as the
- code-serializer, which generates code caches for caching of user script
- code.
- - `src/strings/`: Implementations of string helpers, such as predicates for
- characters, unicode processing, hashing and string building.
- - `src/torque/`: The Torque language implementation.
- - `src/tracing/`: The tracing implementation.
- - `src/trap-handler/`: Implementations of trap handlers.
- - `src/wasm/`: The WebAssembly implementation.
- - `src/zone/`: The implementation of a simple bump-pointer region-based zone
- allocator.
-- `test/`: Folder containing most of the tests and testing code.
-- `include/`: Folder containing all of V8's publicAPI that is used when V8 is
- embedded in other projects such as e.g. the Blink rendering engine.
-- `out/`: Folder containing the results of a build. Usually organized in sub
- folders for the respective configurations.
-
-## Building
-
-The full documentation for building using GN can be found at
-https://v8.dev/docs/build-gn.
-
-Once the initial dependencies are installed, V8 can be built using `gm.py`,
-which is a wrapper around GN and Ninja.
-
-```bash
-# List all available build configurations and targets
-tools/dev/gm.py
-
-# Build the d8 shell for x64 in release mode
-tools/dev/gm.py quiet x64.release
-
-# Build d8 for x64 in debug mode
-tools/dev/gm.py quiet x64.debug
-```
-
-- **release:** Optimized for performance, with debug information stripped. Use
- for benchmarking.
-- **debug:** Contains full debug information and enables assertions. Slower, but
- essential for debugging.
-- **optdebug:** A compromise with optimizations enabled and debug information
- included. Good for general development.
-- **sync:**
- - Use `--sync` to run `gclient sync -D` before building.
- - Use `--sync=force` to run `gclient sync -D --force --reset` before building.
-
-Make sure to pass the `quiet` keyword unless told to otherwise, so that you
-don't waste tokens on compilation progress. Errors will still be reported.
-
-## Debugging
-
-For debugging, it is recommended to use a `debug` or `optdebug` build. You can
-run `d8` with GDB or LLDB for native code debugging.
-
-```bash
-# Example of running d8 with gdb
-gdb --args out/x64.debug/d8 --my-flag my-script.js
-```
-
-V8 also provides a rich set of flags for diagnostics. Some of the most common
-ones are:
-
-- `--trace-opt`: Log optimized functions.
-- `--trace-deopt`: Log when and why functions are deoptimized.
-- `--trace-gc`: Log garbage collection events.
-- `--allow-natives-syntax`: Enables calling of internal V8 functions (e.g.
- `%OptimizeFunctionOnNextCall(f)`) from JavaScript for testing purposes.
-
-A comprehensive list of all flags can be found by running
-`out/x64.debug/d8 --help`. Most V8 flags are in `flag-definitions.h`; flags
-specific to the `d8` shell are located in `src/d8/d8.cc` within the
-`Shell::SetOptions` function.
-
-When debugging issues in Torque code, it is often useful to inspect the
-generated C++ files in `out/<build-config>/gen/torque-generated/`. This allows
-you to see the low-level CodeStubAssembler code that is actually being executed.
-
-## Testing
-
-The primary script for running tests is `tools/run-tests.py`. You specify the
-build output directory and the tests you want to run. Key test suites include:
-
-- **unittests:** C++ unit tests for V8's internal components.
-- **cctest:** Another, older format for C++ unit tests (deprecated, in the
- process of being moved to unittests).
-- **mjsunit:** JavaScript-based tests for JavaScript language features and
- builtins.
-
-```bash
-# Run all standard tests for the x64.optdebug build
-tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug
-
-# Run a specific test suite (e.g., cctest)
-tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug cctest
-
-# Run a specific test file
-tools/run-tests.py --progress dots --exit-after-n-failures=5 --outdir=out/x64.optdebug cctest/test-heap
-```
-
-It's important to pass `--progress dots` so that there is minimal progress
-reporting, to avoid cluttering the output.
-
-If there are any failing tests, they will be reported along their stderr and a
-command to reproduce them e.g.
-
-```
-=== mjsunit/maglev/regress-429656023 ===
---- stderr ---
-#
-# Fatal error in ../../src/heap/local-factory.h, line 41
-# unreachable code
-#
-#
-#
-...stack trace...
-Received signal 6
-Command: out/x64.optdebug/d8 --test test/mjsunit/mjsunit.js test/mjsunit/maglev/regress-429656023.js --random-seed=-190258694 --nohard-abort --verify-heap --allow-natives-syntax
-```
-
-You can retry the test either by running the test name with
-`tools/run-tests.py`, e.g.
-`tools/run-tests.py --progress dots --outdir=out/x64.optdebug mjsunit/maglev/regress-429656023`,
-or by running the command directly. When running the command directly, you can
-add additional flags to help debug the issue, and you can try running a
-different build (e.g. running a debug build if a release build fails).
-
-The full testing documentation is at https://v8.dev/docs/test.
-
-## Coding and Committing
-
-- Always follow the style conventions used in code surrounding your changes.
-- Otherwise, follow
- [Chromium's C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/styleguide.md).
-- Use `git cl format` to automatically format your changes.
-
-### Commit Messages
-
-Commit messages should follow the convention described at
-https:/v8.dev/docs/contribute#commit-messages. A typical format is:
-
-```
-[component]: Short description of the change
-
-Longer description explaining the "why" of the change, not just
-the "what". Wrap lines at 72 characters.
-
-Bug: 123456
-```
-
-- The `component` is the area of the codebase (e.g., `compiler`, `runtime`,
- `api`).
-- The `Bug:` line is important for linking to issues in the tracker at
- https://crbug.com/
-
-## Common Pitfalls & Best Practices
-
-- **Always format before committing:** Run `git cl format` before creating a
- commit to ensure your code adheres to the style guide.
-- **Do not edit generated files:** Files in `out/` are generated by the build
- process. Edits should be made to the source files (e.g., `.tq` files for
- Torque, `.pdl` for protocol definitions).
-- **Match test configuration to build:** Ensure you are running tests against
- the correct build type (e.g., run mjsunit from out/x64.debug if you built
- x64.debug).
-- **Check surrounding code for conventions:** Before adding new code, always
- study the existing patterns, naming conventions, and architectural choices in
- the file and directory you are working in.
-- **Avoid changing unrelated code:** Keep diffs small by only changing the code
- you intended to change. Nearby code should not be cleaned up while making a
- change -- if you think there is a good cleanup, suggest it to me for a
- separate patch.
-- **Keep related functions together:** When adding a new function, try to insert
- it near related functions, to keep similar behaviour close.
-- **Don't guess header names:** If you don't know where the definition of a
- class or function is, don't try to guess the header name, but search for it
- instead.
-- **Be careful with forward declarations:** Many types are forward declared; if
- you want to use them, you'll need to find the definition.
-- **Be careful with inline function definitions:** Many functions are declared
- as `inline` in the `.h` file, and defined in a `-inl.h` file. If you get
- compile errors about a missing definition, you are likely missing an
- `#include` for a `-inl.h` file. You can only include `-inl.h` files from other
- `-inl.h` files and `.cc` files.
diff --git a/deps/v8/agents/prompts/templates/README.md b/deps/v8/agents/prompts/templates/README.md
deleted file mode 100644
index 3cb7bef57a7..00000000000
--- a/deps/v8/agents/prompts/templates/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Prompt Templates
-
-These are prompt snippets that can be used independently or added to a base
-prompt to provide specific context and functionality.
-
-They can be imported by a GEMINI.md file with the `@<path>` syntax:
-
-```src/GEMINI.md
-@agents/prompts/common.md
-@agents/prompts/templates/<example.md>
-```
-
-or used standalone:
-
-```src/GEMINI.md
-@agents/prompts/templates/<example.md>
-```
diff --git a/deps/v8/agents/prompts/templates/modular.md b/deps/v8/agents/prompts/templates/modular.md
index 98f3d463246..144e1f539b0 100644
--- a/deps/v8/agents/prompts/templates/modular.md
+++ b/deps/v8/agents/prompts/templates/modular.md
@@ -1,9 +1,9 @@
-# Gemini Workspace for V8
+# V8 Agent Workspace
-This is the workspace configuration for V8 when using Gemini.
+This is the workspace configuration for V8 coding agents (`jetski-cli`).
For understanding V8 concepts and structure, refer to the
-[v8-understanding](agents/skills/v8-understanding/SKILL.md) skill.
+[v8-understanding](/agents/skills/v8-understanding/SKILL.md) skill.
Some hints:
@@ -14,26 +14,15 @@ Some hints:
- V8 is providing support for running JavaScript and WebAssembly on the web. As
such, it is critical to aim for best possible performance when optimizing V8.
-## Subagents Setup
+## Skills & Rules Setup
-To use the subagents in this repository, you need to run the appropriate
-installation script depending on your environment:
+To install workspace skills and rules:
-- **For Gemini CLI**: Run `vpython3 agents/scripts/install_for_gemini_cli.py` to
- generate the subagent files in `.gemini/agents/`.
- **For Jetski**: Run `vpython3 agents/scripts/install_for_jetski.py` to create
- symlinks in `.agents/agents/`.
-
-## Workspace Subagents
-
-Detailed information has been moved to specialized subagents in
-`agents/agents/`. Use them on demand:
-
-- **Researcher**: Explores the codebase and finds information. See
- `agents/agents/researcher/`.
-- **Builder**: Compiles V8. See `agents/agents/builder/`.
-- **Tester**: Runs tests and benchmarks. See `agents/agents/tester/`.
-- **Debugger**: Investigates crashes using GDB. See `agents/agents/debugger/`.
+ symlinks in `.agents/`.
+- **For GitHub Copilot CLI**: Run
+ `vpython3 agents/scripts/install_for_copilot_cli.py` to install repository
+ instructions and compatible rules/skills in `.github/`.
## Workspace Skills & Rules
@@ -46,11 +35,12 @@ General guidance and reference information are available as skills or rules:
- **Testing**: Detailed guide for running and interpreting tests. See
[v8-testing](/agents/skills/v8-testing/SKILL.md).
- **Best Practices**: Common pitfalls and fix proposal guidelines. See
- [v8_best_practices](/agents/rules/v8-best-practices.md).
+ [v8-best-practices](/agents/rules/v8-best-practices.md).
- **Setup**: Handles missing dependencies and configuration for V8 tools. See
[v8-setup](/agents/skills/v8-setup/SKILL.md).
-- **Git CL Conventions**: Commit message format and usage. See
- [git_cl](/agents/rules/git-cl.md).
+- **Git Commit & CL Conventions**: Commit message format and `git cl` usage. See
+ [git-commit](/agents/rules/git-commit.md) and
+ [git-cl](/agents/rules/git-cl.md).
- **Torque**: Expert guidance for Torque. See
[torque](/agents/skills/torque/SKILL.md).
- **Debugging Workflow**: Guide for issue-based debugging. See
@@ -72,14 +62,13 @@ General guidance and reference information are available as skills or rules:
- Otherwise, follow
[Chromium's C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/styleguide.md).
- Use `git cl format` to automatically format your changes.
-- Follow [git_cl](/agents/rules/git-cl.md) for commit conventions.
+- Follow [git-commit](/agents/rules/git-commit.md) and
+ [git-cl](/agents/rules/git-cl.md) for commit conventions.
- For best practices and common pitfalls, see
- [v8_best_practices](/agents/rules/v8-best-practices.md).
+ [v8-best-practices](/agents/rules/v8-best-practices.md).
## Agent Framework
-- **Mandatory Orchestration**: For any task in V8, the agent MUST act as an
- Orchestrator and use the specialized subagents defined in `agents/agents/`.
-- Follow the rules in `agents/rules/framework.md` and
- `agents/rules/execution_constraints.md`.
-- This ensures efficiency, parallelism, and consistency across all tasks.
+- Follow the rules in
+ [execution-constraints](/agents/rules/execution-constraints.md) for background
+ execution, subagent delegation, and workspace isolation.
diff --git a/deps/v8/agents/rules/debugging.md b/deps/v8/agents/rules/debugging.md
index c3f06ef312b..045482c7b0f 100644
--- a/deps/v8/agents/rules/debugging.md
+++ b/deps/v8/agents/rules/debugging.md
@@ -1,91 +1,47 @@
---
name: debugging-rule
-trigger: always_on
+trigger: model_decision
+description: Guidelines and guardrails for debugging V8 crashes, preserving reproducers, and running GDB
---
-# Mandatory Debugging Workflow (ORCHESTRATION ONLY)
+# Debugging Workflow Guidelines
-When tasked with debugging a crash or investigating unexpected behavior, the
-main agent **MUST** adhere to the following strict constraints:
+When tasked with debugging a crash or investigating unexpected behavior, balance
+direct technical investigation with background execution and targeted
+delegation:
-## 1. Role Restriction: Orchestrator Only
+## 1. Execution & Parallelism
-- Delegate execution of heavy technical investigation tools to specialized
- subagents.
-- Use subagents when running GDB (`gdb-mcp`).
-- Delegate extensive searches or reading large C++ files to subagents.
-- Your sole job is to **Orchestrate**, **Delegate**, and **Synthesize**.
-- **Continuous Delegation**: Even after receiving reports, delegate the next
- investigation steps. Do not take over.
-- **Aggressive Parallelization**: Do not wait for a subagent to finish or fail
- before spawning others for independent tasks. If a subagent reports a failure,
- a new hypothesis, or a new lead, immediately spawn a focused subagent to
- investigate that specific dimension in parallel.
-- **User Interface**: Act strictly as the interface to the user. Keep them
- informed of high-level certainties. You may provide brief status updates on
- running agents.
-- **Naming**: Do not refer to subagents by specific titles (e.g., "Spec Expert")
- in user communications. Use generic descriptions of the inquiry instead.
+- **Start Builds Asynchronously**: Kick off required builds (`gm.py`) in the
+ background immediately and begin reading the reproducing script, stack trace,
+ and relevant C++ code while the build runs.
+- **Direct Investigation Default**: For tightly coupled compiler, GC, or runtime
+ invariants, read the relevant C++ files (via `code_search` and `view_file`)
+ and run GDB (`gdb-mcp` or `d8`) directly to keep full context in a single
+ loop.
+- **Targeted Subagent Delegation**: Spawn subagents (`self` or
+ `research-google`) when investigating genuinely orthogonal hypotheses,
+ performing broad git blame/history archeology, or running independent test
+ suites in parallel.
+- **GDB Resource Management**: Avoid running multiple concurrent GDB sessions on
+ the same binary/build directory unless they are testing independent execution
+ paths.
-## 2. Mandatory First Actions (Three Parallel Tracks)
+## 2. Reproducer & Triage Guardrails
-Upon receiving a debugging task, you MUST immediately initialize the following
-tracks in parallel:
-
-### Track A: Heavy Infrastructure
-
-- Start building (`gm.py`) and preparing for runtime analysis (`gdb-mcp` or
- `rr`) immediately.
-
-### Track B: Conceptual Triage
-
-- **JS Source Reading**: Analyze the reproducing JS script to identify language
- features (e.g., closures, `eval`, TDZ) and runtime flags/hints.
- **Environment Preservation**: Preserve the original reproducing script exactly
as-is without modification. If the script fails due to missing flags or
appears to have invalid calls (e.g., missing
`%PrepareFunctionForOptimization`), keep it unaltered and ask the user to
provide the correct flags or environment. Create scratch copies for
minimization or testing if needed.
-- **Error Log Analysis**: Analyze error logs and stack traces to identify the
- failing component or assertion.
-
-### Track C: Static Research & Eager Delegation
-
-- **V8/Spec Exploration**: Use your internal knowledge to start reading relevant
- V8 C++ code (via `code_search`) and consulting ECMAScript spec requirements
- simultaneously.
-- **Work Branching**: PROACTIVELY spawn subagents (e.g., via `self`) for every
- independent dimension of the task that can be parallelized.
+- **Error Log & Source Triage**: Analyze the reproducing JS script, runtime
+ flags, and assertion stack traces early to narrow down the failing subsystem.
-## 3. Iterative Concept Discovery & Overlap Analysis
+## 3. Synthesis & Communication
-During investigation (especially via GDB or subagent reports):
-
-- **Continuous Discovery**: If you encounter a new internal concept, spawn a
- subagent to research it immediately.
-- **Overlap & Re-evaluation**: Actively check for overlaps between concepts.
- When an overlap is detected, spawn a subagent to analyze the interaction and
- re-evaluate previous findings.
-
-## 4. Synthesis & Communication
-
-- **Proactive Updates**: Keep the user informed of key milestones (e.g., triage
- results, parallel task status).
-- **Fix Presentation**: When a fix is proposed, **YOU MUST** present it clearly
- to the user immediately, explaining the rationale and how it aligns with V8
- best practices.
+- **Fix Presentation**: When a fix is proposed, present it clearly to the user,
+ explaining the root cause, rationale, and how it aligns with V8 best
+ practices.
- **Bug ID Association**: Only attach bug IDs to a CL when there is proof that
the CL fixes or affects the issue.
-
-## 5. Subagent Coordination & Anti-Duplication
-
-- **Centralized Routing**: The main agent MUST monitor subagent tasks to prevent
- duplicate investigations.
-- **Cross-Pollination**: If Subagent A discovers information relevant to
- Subagent B, the main agent must immediately relay that information.
-- **Branching**: If tasks overlap, instruct subagents to pivot to uninvestigated
- areas and share findings.
-- **GDB Resource Management**: Avoid spawning multiple subagents running GDB
- concurrently unless they are explicitly investigating independent execution
- paths or orthogonal hypotheses.
diff --git a/deps/v8/agents/rules/execution-constraints.md b/deps/v8/agents/rules/execution-constraints.md
index 28978b1e436..13a860d1ed8 100644
--- a/deps/v8/agents/rules/execution-constraints.md
+++ b/deps/v8/agents/rules/execution-constraints.md
@@ -19,10 +19,25 @@ To ensure efficient operation and prevent resource waste:
content or guidance if a resource is inaccessible through available tools
(like Buganizer MCP).
-04. **Mandatory Orchestration**: For any complex task or project in V8, the
- agent MUST act as an Orchestrator and use the multi-layered skill framework
- defined in `agents/skills/`. Break down tasks and delegate to subagents to
- maximize parallelism. Avoid sequential execution of independent tasks.
+04. **Pragmatic Parallelism & Subagent Isolation**:
+
+ - **Never wait idle on builds/tests**: Start slow operations (`gm.py` builds
+ or test suites) asynchronously in the background while reading code or
+ analyzing reproducers. Once parallel code analysis is complete, stop
+ calling tools to wait for the automatic completion wakeup rather than
+ polling `manage_task` or `manage_subagents`.
+ - **Keep tightly-coupled work in the main agent**: Read C++ files, trace
+ compiler/GC invariants, and author fixes directly when context needs to be
+ shared tightly.
+ - **Delegate independent or context-heavy work**: Prefer `research-google`
+ (`Workspace: "inherit"`) for read-only codebase, `docs/`, or git history
+ archeology, and `self` when exploring orthogonal hypotheses or executing
+ repeatable batch changes that require running commands or editing files.
+ - **Isolate parallel workspace modifications**: When a `self` subagent or
+ background assistant needs to build or edit files in parallel, create an
+ isolated V8 worktree via `agents/scripts/create_worktree.sh <task_id>`
+ (which runs `tools/dev/setup_worktree_build.py` to symlink `gclient` DEPS)
+ rather than raw `Workspace: "share"`.
05. **Avoid Interactive Pagers**: Always use `--no-pager` or ensure `PAGER=cat`
is set when running commands that might produce long output (e.g.,
diff --git a/deps/v8/agents/rules/framework.md b/deps/v8/agents/rules/framework.md
deleted file mode 100644
index a37bbb13386..00000000000
--- a/deps/v8/agents/rules/framework.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-name: framework-rule
-trigger: always_on
----
-
-# Framework Rule
-
-For any complex task or project, the agent MUST adhere to the multi-layered
-skill framework defined in `.agents/skills/`.
-
-## Core Directives
-
-1. **Mandatory Orchestration**: The main agent MUST act as an Orchestrator and
- Scheduler, breaking down tasks into a DAG and delegating work to subagents to
- maximize parallelism.
-2. **Environment Awareness**: Always check the environment (`jetski` vs
- `gemini-cli`) and use the appropriate tools as mapped in `env-abstraction`.
-3. **Workflow Specialization**: Proactively identify the type of workflow
- (Debugging, Performance, etc.) and activate the corresponding specialized
- skill.
-4. **Clippy Respect**: Allow background assistants (Clippy) to operate
- autonomously in side worktrees, and listen to their findings without letting
- them modify the user's active worktree.
-
-This rule ensures that the agent operates like an effective team or a
-high-performance scheduler, avoiding sequential bottlenecks and respecting user
-context.
diff --git a/deps/v8/agents/rules/v8-best-practices.md b/deps/v8/agents/rules/v8-best-practices.md
index e9864aab070..6609c5c88ef 100644
--- a/deps/v8/agents/rules/v8-best-practices.md
+++ b/deps/v8/agents/rules/v8-best-practices.md
@@ -44,10 +44,30 @@ When proposing a fix, ensure the code adheres to V8 standards:
- **Cleanup Constraint**: Keep diffs small by changing only the code intended
for the task. Propose cleanups to nearby code as a separate patch to keep the
current change focused.
+- **Supported Architectures**: For most changes and bug fixes, it is fine to
+ omit not officially supported architectures and only implement or fix the main
+ four: `ia32`, `x64`, `arm`, and `arm64`. Architectures without official Google
+ support (e.g., `mips64`, `riscv32`, `riscv64`, `s390x`, `ppc64`, `loong64`)
+ are community-maintained and do not need to be updated unless specifically
+ requested or targeted.
## General Best Practices
-For general best practices regarding formatting, generated files, test
-configurations, header names, and forward declarations, refer to Common Pitfalls
-& Best Practices section. This rule file focuses on V8-specific fix proposals
-and technical guardrails.
+- **Always format before committing:** Run `git cl format` before creating a
+ commit to ensure your code adheres to the style guide.
+- **Do not edit generated files:** Files in `out/` are generated by the build
+ process. Edits should be made to the source files (e.g., `.tq` files for
+ Torque, `.pdl` for protocol definitions).
+- **Match test configuration to build:** Ensure you are running tests against
+ the correct build type (e.g., run mjsunit from out/x64.debug if you built
+ x64.debug).
+- **Check surrounding code for conventions:** Before adding new code, always
+ study the existing patterns, naming conventions, and architectural choices in
+ the file and directory you are working in.
+- **Keep related functions together:** When adding a new function, try to insert
+ it near related functions, to keep similar behaviour close.
+- **Don't guess header names:** If you don't know where the definition of a
+ class or function is, don't try to guess the header name, but search for it
+ instead.
+- **Be careful with forward declarations:** Many types are forward declared; if
+ you want to use them, you'll need to find the definition.
diff --git a/deps/v8/agents/scripts/install_for_copilot_cli.py b/deps/v8/agents/scripts/install_for_copilot_cli.py
index 63d2182d27d..7b7fd8dfe7c 100644
--- a/deps/v8/agents/scripts/install_for_copilot_cli.py
+++ b/deps/v8/agents/scripts/install_for_copilot_cli.py
@@ -27,11 +27,6 @@ FRONTMATTER_PATTERN = re.compile(
r"\A(?P<block>---[ \t]*\r?\n(?P<yaml>.*?)\r?\n---[ \t]*)"
r"(?:\r?\n|\Z)", re.DOTALL)
COPILOT_INCOMPATIBLE_RULES = {
- # Mandates orchestration-only operation through subagent and `gdb-mcp`
- # APIs not mapped by this adapter.
- "debugging.md",
- # Hard-codes Jetski/Gemini CLI behavior and adapter paths.
- "framework.md",
# Mandates `TAG=agy` and a conversation ID that this adapter cannot
# supply, which would land in uploaded CL descriptions.
"git-commit.md",
@@ -42,10 +37,6 @@ COPILOT_INCOMPATIBLE_SKILLS = {
"agent-evaluation-framework",
# Mandates a subagent API and model tier not mapped by this adapter.
"doc-invalidation-checker",
- # Maps only Jetski and Gemini CLI tools.
- "env-abstraction",
- # Mandates scheduling and delegation APIs not mapped by this adapter.
- "orchestrator",
# Mandates internal Buganizer, session-context, and delegation APIs not
# provisioned or mapped by this adapter.
"v8-security-triaging",
diff --git a/deps/v8/agents/scripts/install_for_gemini_cli.py b/deps/v8/agents/scripts/install_for_gemini_cli.py
deleted file mode 100755
index f34e91904eb..00000000000
--- a/deps/v8/agents/scripts/install_for_gemini_cli.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env vpython3
-# Copyright 2026 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.
-from __future__ import annotations
-
-import json
-from pathlib import Path
-import yaml
-
-FILE_PATH = Path(__file__).resolve()
-repo_root = FILE_PATH.parents[2]
-src_dir = FILE_PATH.parents[1] / "agents"
-dest_dir = repo_root / ".gemini" / "agents"
-
-# 1. Check if .gemini/agents is a symlink
-if dest_dir.is_symlink():
- print(f"Removing symlink at {dest_dir}")
- dest_dir.unlink()
-
-dest_dir.mkdir(parents=True, exist_ok=True)
-
-for item in src_dir.iterdir():
- if not item.is_dir():
- continue
-
- agent_json_path = item / "agent.json"
- config_yaml_path = item / "config.yaml"
-
- if not (agent_json_path.exists() and config_yaml_path.exists()):
- print(f"Skipping {item.name}: missing agent.json or config.yaml")
- continue
-
- with agent_json_path.open("r") as f:
- agent_json = json.load(f)
- with config_yaml_path.open("r") as f:
- config_yaml = yaml.safe_load(f)
-
- name = agent_json.get("name")
- description = agent_json.get("description")
-
- custom_agent = config_yaml.get("custom_agent", {})
- system_prompt_sections = custom_agent.get("system_prompt_sections", [])
- tool_names = custom_agent.get("tool_names", [])
-
- # Concatenate system prompt sections
- body = ""
- for section in system_prompt_sections:
- body += f"# {section.get('title')}\n\n{section.get('content')}\n\n"
-
- # Map tools to Gemini CLI names
- gemini_tools = []
- for t in tool_names:
- if t == "view_file":
- gemini_tools.append("read_file")
- elif t == "run_command":
- gemini_tools.append("run_shell_command")
- elif t == "list_dir":
- gemini_tools.append("list_directory")
- elif t == "search_web":
- gemini_tools.append("google_web_search")
- elif t == "call_mcp_tool":
- pass
- else:
- gemini_tools.append(t)
-
- # Create frontmatter
- frontmatter = {
- "name": name,
- "description": description,
- "kind": "local",
- "tools": gemini_tools,
- "model": "inherit"
- }
-
- dest_file = dest_dir / f"{name}.md"
- with dest_file.open("w") as f:
- f.write("---\n")
- yaml.dump(frontmatter, f, default_flow_style=False)
- f.write("---\n")
- f.write(body)
-
- print(f"Installed {name}.md for Gemini CLI")
-
-gemini_md_path = repo_root / "GEMINI.md"
-if not gemini_md_path.exists():
- with gemini_md_path.open("w") as f:
- f.write("@[Modular Rules](agents/prompts/templates/modular.md)\n")
- print(f"Created {gemini_md_path}")
-else:
- print(f"Skipping {gemini_md_path} creation since it already exists.")
diff --git a/deps/v8/agents/scripts/install_for_jetski.py b/deps/v8/agents/scripts/install_for_jetski.py
index ea9d9b1cd93..09c7d42df73 100755
--- a/deps/v8/agents/scripts/install_for_jetski.py
+++ b/deps/v8/agents/scripts/install_for_jetski.py
@@ -32,11 +32,20 @@ if agents_dest.is_symlink():
# 2. Ensure .agents is a real directory
agents_dest.mkdir(parents=True, exist_ok=True)
-# Cleanup top-level dead symlinks in .agents/ (e.g. legacy extensions)
+# Cleanup top-level dead symlinks and legacy subdirectories in .agents/
for item in agents_dest.iterdir():
if item.is_symlink() and not item.exists():
print(f"Removing dead top-level symlink {item}")
item.unlink()
+ elif (item.is_dir() and not item.is_symlink() and
+ not (agents_src / item.name).exists()):
+ for sub_item in item.iterdir():
+ if sub_item.is_symlink() and not sub_item.exists():
+ print(f"Removing dead symlink {sub_item}")
+ sub_item.unlink()
+ if not any(item.iterdir()):
+ print(f"Removing empty legacy directory {item}")
+ item.rmdir()
# 3. Process top-level items in agents/
for item in agents_src.iterdir():
@@ -46,7 +55,7 @@ for item in agents_src.iterdir():
dest_item = agents_dest / item.name
- if item.name not in ["agents", "skills", "rules", "plugins"]:
+ if item.name not in ["skills", "rules", "plugins"]:
# For other items, symlink directly
if not dest_item.exists():
create_symlink(item, dest_item)
@@ -77,10 +86,31 @@ for item in agents_src.iterdir():
if not dest_sub.exists():
create_symlink(shared_git_cl_helper, dest_sub)
+modular_rule = "@[Modular Rules](agents/prompts/templates/modular.md)"
gemini_md_path = repo_root / "GEMINI.md"
if not gemini_md_path.exists():
with gemini_md_path.open("w") as f:
- f.write("@[Modular Rules](agents/prompts/templates/modular.md)\n")
+ f.write(f"{modular_rule}\n")
print(f"Created {gemini_md_path}")
else:
- print(f"Skipping {gemini_md_path} creation since it already exists.")
+ content = gemini_md_path.read_text()
+ updated = False
+ if "@agents/prompts/templates/modular.md" in content:
+ content = content.replace("@agents/prompts/templates/modular.md",
+ modular_rule)
+ updated = True
+ if "@agents/prompts/common.md" in content:
+ if modular_rule in content:
+ content = content.replace("@agents/prompts/common.md\n", "")
+ content = content.replace("@agents/prompts/common.md", "")
+ else:
+ content = content.replace("@agents/prompts/common.md", modular_rule)
+ if not content.endswith("\n"):
+ content += "\n"
+ updated = True
+
+ if updated:
+ gemini_md_path.write_text(content)
+ print(f"Upgraded legacy rules in {gemini_md_path}")
+ else:
+ print(f"Skipping {gemini_md_path} creation since it already exists.")
diff --git a/deps/v8/agents/skills/README.md b/deps/v8/agents/skills/README.md
index 6c207a1d5f8..1a4af1e17eb 100644
--- a/deps/v8/agents/skills/README.md
+++ b/deps/v8/agents/skills/README.md
@@ -2,29 +2,25 @@
This directory contains specialized Agent Skills for V8 development.
-Unlike general context files, skills are shared, "on-demand" expertise that
-multiple AI agents (such as Gemini CLI, Claude, GitHub Copilot, etc.) can
-activate when relevant to your request.
+Unlike general context files, skills are shared, "on-demand" expertise that AI
+agents (such as Jetski, Claude, GitHub Copilot, etc.) can activate when relevant
+to your request.
## How to Use
-To use a skill, you must first install it into your workspace. Creating a
-symlink is preferred so that the skill stays up-to-date when you sync your local
+To use skills in Jetski, install them into your workspace `.agents/skills/`
+directory via symlinks so they stay up-to-date when you sync your local
checkout:
```bash
-gemini skills link agents/skills/<skill-name> --scope workspace
+vpython3 agents/scripts/install_for_jetski.py
```
-Once installed, your agent (e.g. the Gemini CLI when using `.gemini/skills`)
-will automatically detect when a skill is relevant to your request and ask for
-permission to activate it.
+Once installed, your agent will automatically detect when a skill is relevant to
+your request and read its `SKILL.md` instructions.
## Contributing
New skills should be self-contained within their own directory under
`agents/skills/`. Each skill requires a `SKILL.md` file at its root with a name
and description in the YAML frontmatter.
-
-Note that gemini-cli comes preloaded with a "skill creator" skill. Most skills
-can be written or improved by asking gemini to do so.
diff --git a/deps/v8/agents/skills/env-abstraction/SKILL.md b/deps/v8/agents/skills/env-abstraction/SKILL.md
deleted file mode 100644
index cf9ace54b5b..00000000000
--- a/deps/v8/agents/skills/env-abstraction/SKILL.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-name: env-abstraction
-description: Handles abstraction of environment-specific commands between Jetski and Gemini-CLI. Use when switching execution context between local terminal environments. Do not use for debugging logic issues.
----
-
-# Environment Abstraction Skill
-
-This skill provides a layer of abstraction over environment-specific tools and
-commands, allowing skills to be reused across different platforms like `jetski`
-and `gemini-cli`.
-
-## Core Principles
-
-1. **Decoupling**: Keep tool calls independent from platform specific
- implementations inside general workflow skills.
-2. **Detection**: Determine the environment at startup (e.g., via environment
- variables or tool availability).
-3. **Mapping**: Map abstract actions to concrete commands or tool calls based on
- the environment.
-
-## Environment Definitions
-
-### Jetski Environment
-
-- **Characteristics**: Rich set of specialized tools (e.g., `code_search`,
- `moma_search`, `gdb-mcp`, `v8-utils`).
-- **Usage**: Prefer specialized tools over generic shell commands to maximize
- efficiency and respect workspace constraints (e.g., avoid heavy searches in
- large workspaces).
-
-### Gemini-CLI Environment
-
-- **Characteristics**: May rely more on standard shell commands or a different
- set of MCP servers.
-- **Usage**: Fall back to standard tools like `grep`, `find`, or standard `gdb`
- via `run_command` if specialized Jetski tools are unavailable.
-
-## Abstract Action Mapping
-
-When performing common actions, refer to this mapping to choose the correct
-tool:
-
-| Abstract Action | Jetski Implementation | Gemini-CLI Implementation (Fallback)
-| | :--- | :--- | :--- | | **Code Search** | `code_search` | `grep_search` (if
-outside Google3) or standard `grep` | | **File Search** | `find_by_name` (if
-safe) | Standard `find` or `fd` | | **Debugging** | `gdb-mcp` | Standard `gdb`
-via `run_command` | | **Building** | `tools/dev/gm.py` (use
-`use_remoteexec=true`) | `tools/dev/gm.py` | | **Testing** |
-`tools/run-tests.py` | `tools/run-tests.py` | | **Starting Agents** |
-`invoke_subagent` (tool) | `agentapi new-conversation` (CLI) |
-
-## Implementation Guidelines
-
-- When writing or updating skills, refer to actions by their abstract names.
-- Check for the existence of specialized tools before falling back to generic
- commands.
-- Document any environment-specific assumptions in the skill file.
diff --git a/deps/v8/agents/skills/orchestrator/SKILL.md b/deps/v8/agents/skills/orchestrator/SKILL.md
deleted file mode 100644
index 8f4d03e20f7..00000000000
--- a/deps/v8/agents/skills/orchestrator/SKILL.md
+++ /dev/null
@@ -1,189 +0,0 @@
----
-name: orchestrator
-description: Core skill for task scheduling and multi-agent coordination in V8 development. Use for any multi-step workflow or complex task. Do not use for simple linear tasks.
----
-
-# Orchestrator Skill
-
-This skill defines the behavior of the Main Agent acting as an Orchestrator and
-Scheduler. It is mandatory for all complex tasks to ensure efficiency,
-parallelism, and correct dependency handling.
-
-## Core Responsibilities
-
-1. **Task Breakdown & DAG Construction**:
-
- - Analyze the high-level goal and break it down into discrete tasks.
- - Model tasks as a Directed Acyclic Graph (DAG) where edges represent
- dependencies.
- - Maintain the DAG in the `task.md` artifact or equivalent representation.
-
-2. **Scheduling & Execution**:
-
- - Identify tasks with satisfied dependencies (in-degree 0) that are ready for
- execution.
- - Delegate ALL ready tasks to specialized subagents. The Orchestrator agent
- MUST NOT execute tasks (like running builds, tests, or benchmarks)
- directly.
- - Maximize parallelism by running independent tasks concurrently.
-
-3. **Priority & Resource Management**:
-
- - Assign priorities to tasks. Critical path tasks get highest priority.
- - Monitor resource usage (context window, active subagents) and throttle
- execution if necessary.
- - Handle priority inversion: if a high-priority task is blocked on a
- low-priority task, elevate the low-priority task.
-
-4. **Communication & Synthesis**:
-
- - Act as the central message broker between subagents.
- - Cross-pollinate information: if Subagent A finds something relevant to
- Subagent B's task, relay it immediately.
- - Synthesize results from multiple streams to form a coherent picture for the
- user.
-
-## Rules of Operation
-
-- **Autonomy with Oversight**: Subagents operate with high autonomy ("YOLO"
- mode) but must report state changes and critical findings to the Orchestrator.
-- **No Independent Branching**: Subagents cannot spawn new top-level workstreams
- without Orchestrator approval. They can request the Orchestrator to add new
- tasks to the DAG.
-- **Continuous Re-evaluation**: As new facts emerge, the Orchestrator must
- re-evaluate the DAG, potentially canceling, pausing, or reprioritizing tasks.
-- **Update Timer**: The Orchestrator agent MUST set a 30-second recurring timer
- using the `schedule` tool to provide synthesized updates to the user,
- preventing long periods of silence.
-- **Responsive Termination**: If the user issues a 'stop' command, immediately
- initiate shutdown of all active subagents and background tasks. Hard-kill any
- subagents that do not terminate gracefully within 30 seconds.
-- **Concept Escalation**: Subagents MUST explicitly highlight unfamiliar
- concepts in their reports. The Orchestrator MUST spawn a dedicated inquiry for
- these concepts immediately.
-- **Eager Subagent Escalation**: Subagents MUST proactively and eagerly ask the
- Orchestrator for help or context when encountering unfamiliar concepts or
- potential blockers, rather than getting bogged down in localized research.
-- **Ambiguous Targets**: If a task target (e.g., a benchmark name, flag, or file
- path) is ambiguous or not found in standard lists, the Orchestrator MUST
- immediately ask the user for clarification instead of guessing or performing
- extensive sequential searches.
-- **Inaccessible Attachments/Resources**: If the intake phase detects that
- critical attachments (e.g., POC script, flags, or reproduction steps) from a
- bug report are inaccessible or redacted, the Orchestrator **MUST** stop
- immediately and ask the user to provide them manually.
-- **Resumption After Information Provision**: Once the user provides the missing
- information, the Orchestrator **MUST** immediately restart the affected
- intake/research phase with the new data to ensure all subsequent technical
- steps (expert identification, reproduction, etc.) are based on complete
- information.
-- **Domain Context Awareness**: Do NOT assume terms in a task description refer
- to the environment (e.g., assuming "WSL" means the OS) if they could be
- domain-specific (e.g., a benchmark name). Verify with domain documentation or
- tools first before taking action.
-- **Forced Parallelization**: The Orchestrator MUST identify at least two
- parallel tracks for any complex task before proceeding with execution. Do not
- perform work sequentially if it can be delegated to subagents to maximize
- concurrency.
-- **Utilize Wait Time**: If a task involves a long wait (e.g., a V8 build), the
- Orchestrator MUST schedule independent research or analysis tasks to run in
- parallel. Do not let the main agent or subagents go idle or do trivial work if
- there are unanswered questions.
-- **Environment-Aware Delegation**: When delegating tasks to subagents, use the
- appropriate method for the current environment. In `gemini-cli`, use
- `agentapi new-conversation` (CLI) instead of the `invoke_subagent` tool, which
- may not be available. Make sure to pass critical environment variables
- explicitly to the subagent in its prompt, specifically passing `PATH`
- containing `depot_tools` and any settings for `remoteexec` (siso).
-- **Subagent Isolation Enforcement**: When delegating tasks that involve
- modifying code, building, or running tests that could affect the workspace
- state, the Orchestrator MUST ensure the task is scheduled in an isolated
- worktree. Do not let subagents operate on the main workspace for destructive
- or environment-polluting tasks.
-- **Post-Task Self-Reflection & Divergence Analysis**: After the task is
- complete:
- - **Analyze Process**: Review the session logs.
- - **Divergence Analysis**: If the final landed fix/result differs from the
- agent's initial proposal:
- - Identify *why* the initial proposal was rejected or modified.
- - Determine if the agent was "too hasty" or missed critical invariants.
- - Trace the logical gap in the investigation.
- - **Process Refinement**: Formulate proposals to update skills based on
- lessons learned, and implement them in separate, dedicated CLs.
-- **Workspace and Branch Management**: Always base new branches on a clean
- upstream (e.g., `origin/main`). Avoid creating spurious CLs or polluting
- existing CLs with unrelated changes. Use isolated worktrees for tasks that
- modify the workspace state.
-
-## Specialized Subagents
-
-The Orchestrator delegates tasks to the following specialized subagents:
-
-- **`researcher`**: Prompted to find relevant code, documentation, and
- information in the V8 codebase and the web. Reports findings with file paths
- and line numbers.
-- **`builder`**: Prompted to compile V8 for specified configurations. Can read
- files and search code to understand build errors.
-- **`tester`**: Prompted to run tests and benchmarks and report results. Can
- read files and search code to understand test failures.
-- **`debugger`**: Prompted to investigate crashes and unexpected behavior using
- GDB and other tools.
-
-## Advanced Scheduling & DAG Management
-
-- **Directed Acyclic Graph (DAG)**: The Orchestrator must maintain the task list
- as a DAG to handle dependencies correctly.
-- **Dynamic Re-planning**: When a subagent discovers new information or a task
- fails, the Orchestrator must dynamically update the DAG (adding, removing, or
- reordering tasks).
-- **Eager Parallelism**: Identify independent branches of the DAG and execute
- them in parallel by spawning multiple subagents or background tasks.
-
-## Handling Priority Inversion
-
-- **Priority Inheritance**: If a high-priority task (e.g., fixing a blocker)
- depends on the completion of a low-priority task (e.g., running a clean build
- or documentation), the low-priority task must temporarily inherit the higher
- priority to resolve the dependency.
-- **Resource Contention Awareness**: Ensure that low-priority tasks do not hold
- onto exclusive resources (like GDB sessions or specific build targets) needed
- by high-priority tasks.
-
-## Fair Scheduling & Starvation Prevention
-
-- **Task Aging**: To prevent low-priority tasks from being indefinitely starved
- by a stream of high-priority tasks, increase their priority based on the time
- they have spent in the queue.
-- **Guaranteed Resource Allocation**: Allocate a small but fixed percentage of
- resources or agent attention to lower-priority maintenance or exploratory
- tasks.
-
-## Communication and Synthesis Rules
-
-- **Concise User Communication**: Do not over-explain assumptions or potential
- confusions to the user. State what the plan is based on the interpreted
- context and proceed. Avoid wordy justifications.
-
-- **Structured Reporting**: Subagents must report results in a structured
- format, highlighting:
-
- - Key findings or answers to the assigned question.
- - Blockers or new unfamiliar concepts.
- - Proposed next steps.
-
-- **Synthesis Before Escalation**: The Orchestrator must not simply pass
- subagent reports to the user. It must synthesize the reports from all active
- tasks into a coherent state summary and present only the high-level
- certainties and decisions to the user.
-
-- **Proactive Context Sharing**: The Orchestrator must relay relevant
- discoveries between subagents working on overlapping or dependent tasks to
- avoid duplicate work.
-
-## Analogies to Operating System Schedulers
-
-- **Task = Process/Thread**: A discrete unit of work.
-- **Dependencies = Synchronization Primitives**: Tasks wait on other tasks to
- complete (join).
-- **Orchestrator = Kernel Scheduler**: Decides what runs when and on which "CPU"
- (subagent).
diff --git a/deps/v8/agents/skills/subagent-env-passing/SKILL.md b/deps/v8/agents/skills/subagent-env-passing/SKILL.md
deleted file mode 100644
index 874ebdbec47..00000000000
--- a/deps/v8/agents/skills/subagent-env-passing/SKILL.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-name: subagent-env-passing
-description: Workflow for passing environment variables (like PATH) from the Orchestrator to subagents. Use when spawning subagents that need specific environment variables. Do not use for standard subagent execution.
----
-
-# Subagent Environment Passing Skill
-
-This skill documents how to ensure subagents have access to the correct
-environment variables (such as `PATH`) when working in isolated environments
-like worktrees.
-
-## Workflow
-
-1. **Retrieve Environment**: The Orchestrator should read the necessary
- environment variables from its own context if they are not already known. For
- example, run `echo $PATH` to get the current PATH.
-2. **Pass to Subagent**: When invoking a subagent, include the environment
- variable values in the `Prompt` provided to the subagent.
-3. **Instruct Subagent**: Explicitly instruct the subagent to set these
- variables in its environment before running tools that depend on them.
-
-## Example Prompt Snippet
-
-```
-Please use the following PATH and build settings in your environment:
-export PATH=<path_to_depot_tools>:$PATH
-export SISO_PROJECT=rbe-chrome-untrusted
-
-```
-
-Note: If building or running `gm.py`, also ensure that `use_remoteexec = true`
-is set in your build config/`args.gn`. You can find the correct `SISO_PROJECT`
-in `build/config/siso/.sisoenv`.
diff --git a/deps/v8/agents/skills/v8-regression-testing/SKILL.md b/deps/v8/agents/skills/v8-regression-testing/SKILL.md
index 18093db9cc5..9e4ab2c768b 100644
--- a/deps/v8/agents/skills/v8-regression-testing/SKILL.md
+++ b/deps/v8/agents/skills/v8-regression-testing/SKILL.md
@@ -104,7 +104,7 @@ think you know about the bug, and deepen your understanding.
______________________________________________________________________
-## Synctatic Principles of a Good Regression Test
+## Syntactic Principles of a Good Regression Test
### 1. Minimal & "Leaf" Compiler Flags
@@ -137,6 +137,11 @@ Avoid default fuzzer variable and function names (`__f_0`, `__v_10`, `v17`,
required to reproduce the issue.
- Do not include catch-all blocks (`catch (e) {}`) or dummy wrapper functions
(`__wrapTC`) unless they are semantically required to trigger the crash path.
+- **Do not explicitly load `mjsunit.js`**: `mjsunit` tests run via
+ `tools/run-tests.py` automatically include `test/mjsunit/mjsunit.js`. Never
+ include `d8.file.execute('test/mjsunit/mjsunit.js')` in the test file itself.
+ (When executing the test manually via `d8`, pass `test/mjsunit/mjsunit.js` on
+ the command line instead).
### 4. Deterministic Optimization Control
@@ -148,3 +153,12 @@ Avoid default fuzzer variable and function names (`__f_0`, `__v_10`, `v17`,
- `%OptimizeFunctionOnNextCall(foo);` or `%OptimizeMaglevOnNextCall(foo);`
- Make sure `--allow-natives-syntax` is included in the Flags header when using
percent (`%`) intrinsics.
+
+### 5. Rely on Test Runner Variants for Execution Coverage
+
+- V8's test runner automatically executes test suites across different variants
+ (such as baseline execution, optimizing tiers, and stress modes).
+- Avoid manually forcing execution across multiple tiers or duplicating
+ invocations solely to cover different compiler pipelines, unless the test
+ specifically exercises tier-up dynamics, on-stack replacement, or
+ deoptimization transitions between them.
diff --git a/deps/v8/agents/skills/v8-security-triaging/SKILL.md b/deps/v8/agents/skills/v8-security-triaging/SKILL.md
index 6e2e40f09b6..0144f72d27c 100644
--- a/deps/v8/agents/skills/v8-security-triaging/SKILL.md
+++ b/deps/v8/agents/skills/v8-security-triaging/SKILL.md
@@ -122,7 +122,9 @@ Buganizer.
- **Version and Commit Identification**: Always retrieve the current V8 version
number from `src/utils/version.h` and the specific git hash using
`git rev-parse HEAD`. Prioritize referencing specific git hashes over generic
- terms like "HEAD" in triage reports.
+ terms like "HEAD" in triage reports. For any commit referenced in the report,
+ retrieve its Gerrit changelist link (from `Reviewed-on:` in
+ `git log -n 1 --format=%b <hash>`).
- **Attachment Check**: Ensure the subagent checks for mentioned files (e.g.,
"poc.html", "crash.log") that are NOT in the attachments list. If retrieval of
an attachment via MCP tools fails, the subagent **MUST** use the
@@ -218,7 +220,9 @@ Draft a concise synthesis based on verified subagent findings.
[triaging.md](../../../docs/security/triaging.md) and Chromium guidelines.
- **Introduced In / Regression Range**: Provide the commit or version where
- the vulnerability was introduced, if identifiable.
+ the vulnerability was introduced, if identifiable. Always include a
+ clickable markdown link to the commit's Gerrit changelist (e.g.
+ `[commit <hash>](https://chromium-review.googlesource.com/c/v8/v8/+/<cl>)`).
- **Rationale**: Explain the technical conclusion. For sandbox bypasses,
explicitly state if it violates the threat model.
@@ -226,8 +230,8 @@ Draft a concise synthesis based on verified subagent findings.
- **Local Reproduction Findings**: Follow the structure and mandatory fields
defined in the **Classification Guidelines** of `v8-poc-classification`.
Ensure all technical data (Status, Reproduction command, Result, Build
- (including version from `src/utils/version.h` and git hash), Verified
- Impact, and optional GDB Backtrace) is included here.
+ (including version from `src/utils/version.h` and git hash with a Gerrit
+ link), Verified Impact, and optional GDB Backtrace) is included here.
- **Proposed Owner**: Based on expert discovery. Include a very short (half
sentence) explanation for the choice (e.g., "author of affected code",
@@ -299,6 +303,8 @@ Finalize the session by securing artifacts and cleaning up the environment.
flag (`--run-as-[sandbox]-security-poc`)?
- [ ] **Mandatory Data**: Are the V8 version and git hash included in the Build
description?
+- [ ] **Gerrit Links**: Are all referenced commits and CLs (introduction CL,
+ build commit, etc.) linked to their corresponding Gerrit changelists?
- [ ] **Formatting**: Are there double line breaks between all top-level
bulleted list items? Are sub-bullets indented by at least four spaces without
internal double line breaks?
diff --git a/deps/v8/agents/skills/v8-structure/SKILL.md b/deps/v8/agents/skills/v8-structure/SKILL.md
index 17b3762b4ff..ce65e7ffd43 100644
--- a/deps/v8/agents/skills/v8-structure/SKILL.md
+++ b/deps/v8/agents/skills/v8-structure/SKILL.md
@@ -26,9 +26,9 @@ components.
via macro assemblers, higher level codegen via CodeStubAssembler,
definitions of machine code metadata like safepoint tables and source
position tables, and `compiler.cc` which defines entry points into the
- compilers. This contains subdirectories for architecture specific
- implementations, which should be kept in sync with each other as much as
- possible.
+ compilers. This contains subdirectories for architecture-specific
+ implementations (only the main officially supported architectures `ia32`,
+ `x64`, `arm`, and `arm64` need to be maintained for most changes).
- `src/common/`: Common definitions and utilities.
- `src/compiler/`: The TurboFan optimizing compiler, including the Turboshaft
CFG compiler.
@@ -57,8 +57,9 @@ components.
- `src/profiler/`: The in-process profiler implementations, for heap
snapshots, allocation tracking, and a sampling CPU profiler.
- `src/regexp/`: The regular expression implementation. This contains
- subdirectories for architecture specific implementations, which should be
- kept in sync with each other as much as possible.
+ subdirectories for architecture-specific implementations (as with codegen,
+ only the main officially supported architectures `ia32`, `x64`, `arm`, and
+ `arm64` need to be maintained for most changes).
- `src/runtime/`: C++ functions that can be called from JavaScript at runtime.
- `src/sandbox/`: The implementation of the sandbox, which is a security
feature that attempts to limit V8 memory operations to be within a single
@@ -102,3 +103,11 @@ components.
- `docs/snapshot/`: Snapshot and serialization.
- `docs/torque/`: Torque language and builtins.
- `docs/wasm/`: WebAssembly implementation.
+
+## Supported Architectures
+
+For most changes and bug fixes, it is fine to omit not officially supported
+architectures and only implement or fix the main four: `ia32`, `x64`, `arm`, and
+`arm64`. Architectures without official Google support (e.g., `mips64`,
+`riscv32`, `riscv64`, `s390x`, `ppc64`, `loong64`) are community-maintained and
+do not need to be updated unless specifically requested or targeted by the task.
diff --git a/deps/v8/agents/vpython.toml b/deps/v8/agents/vpython.toml
new file mode 100644
index 00000000000..d9f6ab4bf58
--- /dev/null
+++ b/deps/v8/agents/vpython.toml
@@ -0,0 +1,40 @@
+# Copyright 2026 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.
+
+requires-python = '>=3.11,<3.12'
+dependencies = [
+ 'pyyaml==5.4.1+chromium.1',
+ 'tabulate==0.9.0',
+ 'platformdirs==4.9.2',
+ 'mcp==1.9.4',
+ 'pydantic==2.11.7',
+ 'starlette==0.47.1',
+ 'anyio==4.9.0',
+ 'sniffio==1.3.0',
+ 'idna==3.4',
+ 'typing-extensions==4.13.2',
+ 'httpx-sse==0.4.1',
+ 'httpx==0.28.1',
+ 'certifi==2025.4.26',
+ 'httpcore==1.0.9',
+ 'h11==0.16.0',
+ 'pydantic-settings==2.10.1',
+ 'python-multipart==0.0.20',
+ 'sse-starlette==2.4.1',
+ 'uvicorn==0.35.0',
+ 'annotated-types==0.7.0',
+ 'pydantic-core==2.33.2',
+ 'typing-inspection==0.4.1',
+ 'python-dotenv==1.1.1',
+ 'click==8.0.3',
+ 'colorama==0.4.1',
+ 'perfetto==0.16.0',
+ 'protobuf==6.33.5',
+ 'pandas==2.2.3+chromium.1',
+ 'numpy==1.23.5+chromium.4',
+ 'python-dateutil==2.9.0',
+ 'pytz==2025.2',
+ 'six==1.17.0',
+ 'tzdata==2025.2'
+]
diff --git a/deps/v8/agents/vpython.toml.uv.lock b/deps/v8/agents/vpython.toml.uv.lock
new file mode 100644
index 00000000000..7c421e82d94
--- /dev/null
+++ b/deps/v8/agents/vpython.toml.uv.lock
@@ -0,0 +1,270 @@
+annotated-types==0.7.0 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
+ --hash=sha256:cb8e356aea87fe54a7fb5a59e71f508deff791fda0b1a5f1eedffdcc1fe16672
+ # via pydantic
+anyio==4.9.0 \
+ --hash=sha256:428d7a13cbbc94e1c362cded4273280d4e486efe1e518bba067327fb0792514b \
+ --hash=sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c
+ # via
+ # httpx
+ # mcp
+ # sse-starlette
+ # starlette
+certifi==2025.4.26 \
+ --hash=sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3 \
+ --hash=sha256:f33ffedf5d31d74f9692dd30f5d8e553027a4e5b407cf931d5c9d5c583bd8fad
+ # via
+ # httpcore
+ # httpx
+click==8.0.3 \
+ --hash=sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3 \
+ --hash=sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3 \
+ --hash=sha256:b0a0492d07c8e7e4a88ee153ca6553d357a0746792d6868bfca79dc1a344bb1b
+ # via uvicorn
+colorama==0.4.1 \
+ --hash=sha256:758fb3cafa52391ea645703f283afd57f002011140d470793379790398876733 \
+ --hash=sha256:758fb3cafa52391ea645703f283afd57f002011140d470793379790398876733 \
+ --hash=sha256:758fb3cafa52391ea645703f283afd57f002011140d470793379790398876733 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48 \
+ --hash=sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48
+ # via click
+h11==0.16.0 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 \
+ --hash=sha256:67d7bfdfcac864327f0dc38606322e89b246ffe5f6b4e86c4c9fd5116500f3a5
+ # via
+ # httpcore
+ # uvicorn
+httpcore==1.0.9 \
+ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \
+ --hash=sha256:9b6c124dac46a7e51898765b289fa68480d92c9f26e464d2d6bf1669fa4d03ec
+ # via httpx
+httpx==0.28.1 \
+ --hash=sha256:ae442346a10b89fbfeaa174019b1d012a7cc2f957f6b42994dd270154dd25618 \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad \
+ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad
+ # via mcp
+httpx-sse==0.4.1 \
+ --hash=sha256:2a59b1e5c0558a031568b229d318dca516bc551ab7a311e1d1c5e8a5e8140d6b \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37 \
+ --hash=sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37
+ # via mcp
+idna==3.4 \
+ --hash=sha256:52926a5baa595cfe5376963d8c5bbed33c4c83628dbd1958fc5734d664701b0c \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
+ # via
+ # anyio
+ # httpx
+mcp==1.9.4 \
+ --hash=sha256:78959d9958e78edfea30c9d1ea6da5d07ef17fdf0f64655dec2a8207700a5013 \
+ --hash=sha256:7fcf36b62936adb8e63f89346bccca1268eeca9bf6dfb562ee10b1dfbda9dac0
+numpy==1.23.5+chromium.4 \
+ --hash=sha256:1f09f09cd02263534f3f3376dc290bb33b2d16c10eb85fd1b0491b02028f559c \
+ --hash=sha256:298e858d71fd8e2d963414be9d85288f4e04df92c1025128d7917b42a82768cd \
+ --hash=sha256:3b6a0b96bcd6ce7393a92adbc00892d4af02f6c04936f671979dc285d9ed7c38 \
+ --hash=sha256:3f58475348b7b887ebc9cf63ec63173b52acf988faa9d8e5b797c7befbf9a1c4 \
+ --hash=sha256:44e321bb428153a6e396e7328d808def77c3cef8b3d93c5f9e4108d04c558997 \
+ --hash=sha256:48f8428d17325de892ac883561d6ba485978f7b924e0b610d9f31ce968dbabe9 \
+ --hash=sha256:5af4510cebaf0bb81ea9af5368fbf5a6ce21b4963dbd3e31fe0f796cffefc9ab \
+ --hash=sha256:69098ac2618e6a95064a9096b8eb1e8a737b2105aeec1a21b4eac62ba8d48fa7 \
+ --hash=sha256:785d2cec75a1dfb812be1a3a24da0c82ba60729c7b53e6bd132fda1479f6250f \
+ --hash=sha256:9241565b3fb920fed1268068efbc0e46fbc4f2d6056495574507adaa32741f5d \
+ --hash=sha256:929b83e970651c3971f1cb83ed2c3345266507487702155cb7007d2507d18771 \
+ --hash=sha256:9b59a1ae3c94fd499099e304a23dacb486c030f13e826f79eb77470fa618d979 \
+ --hash=sha256:a5706db7526e7edfafafe4fe620625c346a30f4b97acc8484f55ec5e83d25a74 \
+ --hash=sha256:b80a749316f06b7d6a48cb1e7c5b0cf3de9a2b4ac6d001b3a6a0e5e800ea0f20 \
+ --hash=sha256:eaf5507daa4d82341ad08bb2e5fd780c10e021ad48f8555ebf36027e2809787f
+ # via
+ # --override /tmp/overrides.txt
+ # pandas
+pandas==2.2.3+chromium.1 \
+ --hash=sha256:21c49f76db22c6f13370b357112ac28443d0b57c8c8476613385caa5bf8d7d23 \
+ --hash=sha256:3322b4dba5f4d132abb393e202f22ec7777db4b9b5e7eddba5060ead0d975169 \
+ --hash=sha256:c6f279f603a83f59fbc1b61306e644ca82c48b61ada7b335aa6dbb63c1e38f12 \
+ --hash=sha256:d30cace0d7fc615a216e863bbda793f9eb8ed83b561af458bcbc6d7c421ddc63
+perfetto==0.16.0 \
+ --hash=sha256:2394a32261988f0fb954dd5484c8c2488da7a75636db136399133acf08f515e8 \
+ --hash=sha256:26c9e802763b06da9215d4437a56c2decb4e5e3156c8a7345454501d18a9664c
+platformdirs==4.9.2 \
+ --hash=sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd \
+ --hash=sha256:ef245e78eb7a2ba57599bdb39c4ff323cfae3de356a47207b58bb29e7f479f46
+protobuf==6.33.5 \
+ --hash=sha256:2d7cd4c2152df61dea8147caa60d428960d506c2fb85e1f4a979ec8b0d5ae4fc \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02 \
+ --hash=sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02
+ # via perfetto
+pydantic==2.11.7 \
+ --hash=sha256:bf0c40ec69cef6193c091301b363bcb3e32f39c1ae39117accf81b8c6a21b898 \
+ --hash=sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b
+ # via
+ # mcp
+ # pydantic-settings
+pydantic-core==2.33.2 \
+ --hash=sha256:03678d8617c2f4039931ab83bf88bf5ae7e411e7f21c9d829367851c8c9a117d \
+ --hash=sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef \
+ --hash=sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f \
+ --hash=sha256:12a778136a420910394ff5566e5ac8ee0c1e6fcbcafd955d92c16e61bacde3d2 \
+ --hash=sha256:3bf1e7157dc5769d118fd8b2c30314d19f31e686b22c50fc58bc6892f1fa1951 \
+ --hash=sha256:3c9ce744525d5dada80dfa669fe94a1d590c4604702ebba60e9df61dfb0a09b4 \
+ --hash=sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7 \
+ --hash=sha256:899654b3dbcbdcc87293085ef59d826f762603d5b395d96df972669ac2512632 \
+ --hash=sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d \
+ --hash=sha256:aff6903e22e7ee9e1d2eef334918b8ec93ed4153c252ae6878528a9b03ee5512 \
+ --hash=sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9 \
+ --hash=sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f \
+ --hash=sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f \
+ --hash=sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6
+ # via pydantic
+pydantic-settings==2.10.1 \
+ --hash=sha256:881fc1c77dc4f8396d2965cd82f15909d776750eb72ae05166135a27c1f584e5 \
+ --hash=sha256:a60952460b99cf661dc25c29c0ef171721f98bfcb52ef8d9ea4c943d7c8cc796
+ # via mcp
+python-dateutil==2.9.0 \
+ --hash=sha256:cbf2f1da5e6083ac2fbfd4da39a25f34312230110440f424a14c7558bb85d82e \
+ --hash=sha256:d6e8ba261767bc6626b87eafbaff60e52b68417ae5d245ba5b703e59a384a169
+ # via pandas
+python-dotenv==1.1.1 \
+ --hash=sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc \
+ --hash=sha256:ac4a2ac45f7e1f94c09e819da5d582fbf5a2a3fcf22800fb61433f54f63d88d9
+ # via pydantic-settings
+python-multipart==0.0.20 \
+ --hash=sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104 \
+ --hash=sha256:99087ff3f8f0f3b8f37bec5111c1446c70a74c28fcf24c3e937c7819f4dd27dc
+ # via mcp
+pytz==2025.2 \
+ --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 \
+ --hash=sha256:e14ffd5ea85d3acc73cb4fe5df3ef59e768f56e8b01c35197147a89988c7179e
+ # via pandas
+pyyaml==5.4.1+chromium.1 \
+ --hash=sha256:30943bf7ffc77849ab34b0c9a0bfdd2841d6cfef80a048443088c3981c3b7454 \
+ --hash=sha256:30943bf7ffc77849ab34b0c9a0bfdd2841d6cfef80a048443088c3981c3b7454 \
+ --hash=sha256:34de1c37474ed237b506bed193c3aa961136fb6c56d43c731b639a4658a561c7 \
+ --hash=sha256:3bb84571b42414183e96cc560b602c0b907174dc2ca45bfe28e53371d34a3573 \
+ --hash=sha256:3bf690dd33f9adb2493b54eed0eccedbb5dac7c38977dafbd6c5aaff4c2b9e72 \
+ --hash=sha256:4db0e513d46d3feedff69b33fb4093a899396b6795b790d9b1a9ed84c9de9b83 \
+ --hash=sha256:5cd00e9800df4255d79711cdfd039d957c5a06521ee6e4068efceca9ce09c333 \
+ --hash=sha256:5ef917f3c0447944e3c6a2d6feb7e4c96cadc912436e0bec593d6676438723e9 \
+ --hash=sha256:846e35c9c099b8d9a0b3c4c37444ef38dc9fbf9596f485565cdfa8b6bf33b8a4 \
+ --hash=sha256:9626a7a5bbf3ba01f18eeb6dab7e1a8218bc554a5425103335ed726421f16dac \
+ --hash=sha256:a757e3dbf41d474b343a1c9300051aad6857ba811a5b0844b229c9a81302b3e4 \
+ --hash=sha256:d3624a91bf9acba3a3753052056d59012ee303bba33685d9332077d0029fadbf \
+ --hash=sha256:d3624a91bf9acba3a3753052056d59012ee303bba33685d9332077d0029fadbf \
+ --hash=sha256:d901525f60a95a76c9c7fb87968355e9c76d88b538a84b7319b37219bfa4f37c \
+ --hash=sha256:e0f28dad378280bf0bfb1d3019c8b1dee1894f138f09643a10362235d3495be1 \
+ --hash=sha256:ed50a1341d0580c1ee4f8e381beb56d141df93ab1690fbe9d6b49df55215f318
+six==1.17.0 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:f5f26efe5825ae15ed1e5b419d3225e6b5a92eae4fcb1177f11927682c6a01b4
+ # via python-dateutil
+sniffio==1.3.0 \
+ --hash=sha256:cd5f10406452e65ebd91db488adc3e51cab18f50b7edd4640b0bf88948b2adda \
+ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384
+ # via anyio
+sse-starlette==2.4.1 \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:08b77ea898ab1a13a428b2b6f73cfe6d0e607a7b4e15b9bb23e4a37b087fd39a \
+ --hash=sha256:d003715d225944e99f80a8f86429186b236943caf33a8d1021ad1ec75daa1ec5
+ # via mcp
+starlette==0.47.1 \
+ --hash=sha256:5e11c9f5c7c3f24959edbf2dffdc01bba860228acf657129467d8a7468591527 \
+ --hash=sha256:70b404a8ac9f2ef6d675e0962aa19e5237a094f3049aef195fc0d70c4138d3b6
+ # via mcp
+tabulate==0.9.0 \
+ --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f \
+ --hash=sha256:2a24680b2b6348637deffb72547372f2726d34726cdbd7b8ffbd3218208a7b34
+typing-extensions==4.13.2 \
+ --hash=sha256:9c32564c5ad29ea1284d73bf0026bd46a38554322643136080c36555b4601c59 \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
+ --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c
+ # via
+ # anyio
+ # pydantic
+ # pydantic-core
+ # starlette
+ # typing-inspection
+typing-inspection==0.4.1 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
+ --hash=sha256:420306879f55a5ea78991532847da46039ce9a899340211e7db84b6dbe6e91b2
+ # via
+ # pydantic
+ # pydantic-settings
+tzdata==2025.2 \
+ --hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 \
+ --hash=sha256:259d0754e270da739e95ad473d5adbcff926c9657914b325cc64f5048cfbe39d
+ # via pandas
+uvicorn==0.35.0 \
+ --hash=sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a \
+ --hash=sha256:57e22a1f2fa7f9bfbe555aafa2f4b39bdf7d4eb5494a31399a80ed00ad883a29
+ # via mcp
diff --git a/deps/v8/experimental/OWNERS b/deps/v8/experimental/OWNERS
new file mode 100644
index 00000000000..72e8ffc0db8
--- /dev/null
+++ b/deps/v8/experimental/OWNERS
@@ -0,0 +1 @@
+*
diff --git a/deps/v8/experimental/README.md b/deps/v8/experimental/README.md
new file mode 100644
index 00000000000..f9c209d2f64
--- /dev/null
+++ b/deps/v8/experimental/README.md
@@ -0,0 +1,7 @@
+# Experimental
+
+This is a directory where anything goes - a place for experiments and tools
+which are not code reviewed and/or do not meet the quality standards of the
+rest of the codebase.
+
+Create a subdirectory for your project and commit there.
diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl
index 99905a48ca7..ad0d42bfa39 100644
--- a/deps/v8/include/js_protocol.pdl
+++ b/deps/v8/include/js_protocol.pdl
@@ -143,7 +143,7 @@ domain Debugger
optional Location startLocation
# Location in the source code where scope ends
optional Location endLocation
- # True if the scope does not declare any variables or have a runtime context.
+ # True if the scope does not declare any variables.
# Only present if true.
# Empty scopes are retained in the scope chain because
# they can be targeted via `evaluateOnCallFrame` (using `scopeNumber`) or
diff --git a/deps/v8/include/v8-array-buffer.h b/deps/v8/include/v8-array-buffer.h
index 7d877608003..839630680d7 100644
--- a/deps/v8/include/v8-array-buffer.h
+++ b/deps/v8/include/v8-array-buffer.h
@@ -62,6 +62,11 @@ class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase {
*/
size_t ByteLength() const;
+ /**
+ * Returns the contents of this backing store as a span of bytes.
+ */
+ std::span<uint8_t> ByteSpan() const;
+
/**
* The maximum length (in bytes) that this backing store may grow to.
*
diff --git a/deps/v8/include/v8-callbacks.h b/deps/v8/include/v8-callbacks.h
index 456af07fe1d..efa9de29307 100644
--- a/deps/v8/include/v8-callbacks.h
+++ b/deps/v8/include/v8-callbacks.h
@@ -22,6 +22,7 @@ struct _EXCEPTION_POINTERS;
namespace v8 {
+class ArrayBuffer;
template <typename T>
class FunctionCallbackInfo;
class Isolate;
@@ -470,6 +471,13 @@ using HostCreateShadowRealmContextCallback =
using IsJSApiWrapperNativeErrorCallback = bool (*)(Isolate* isolate,
Local<Object> obj);
+/**
+ * ArrayBufferDetachCallback is called when an ArrayBuffer wrapping an embedder
+ * object is detached.
+ */
+using ArrayBufferDetachCallback = void (*)(Isolate* isolate,
+ Local<ArrayBuffer> buffer);
+
/**
* PrepareStackTraceCallback is called when the stack property of an error is
* first accessed. The return value will be used as the stack value. If this
diff --git a/deps/v8/include/v8-context.h b/deps/v8/include/v8-context.h
index 6608be2d621..8da2c8e48c1 100644
--- a/deps/v8/include/v8-context.h
+++ b/deps/v8/include/v8-context.h
@@ -478,11 +478,15 @@ Local<Value> Context::GetEmbedderData(int index) {
I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
int value_offset =
I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
- A value = I::ReadRawField<A>(embedder_data, value_offset);
#ifdef V8_COMPRESS_POINTERS
- // We read the full pointer value and then decompress it in order to avoid
- // dealing with potential endianness issues.
- value = I::DecompressTaggedField(embedder_data, static_cast<uint32_t>(value));
+ // The tagged payload lives in the low kTaggedSize half of the slot (at
+ // kTaggedPayloadOffset == 0). Read it as a 32-bit field so the correct half
+ // is picked on both little and big endian targets. A full width read plus
+ // truncation would return the CppHeap pointer half on big endian.
+ uint32_t compressed = I::ReadRawField<uint32_t>(embedder_data, value_offset);
+ A value = I::DecompressTaggedField(embedder_data, compressed);
+#else
+ A value = I::ReadRawField<A>(embedder_data, value_offset);
#endif
auto* isolate = I::GetCurrentIsolate();
@@ -501,11 +505,15 @@ V8_INLINE Local<Data> Context::GetEmbedderDataV2(int index) {
I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
int value_offset =
I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
- A value = I::ReadRawField<A>(embedder_data, value_offset);
#ifdef V8_COMPRESS_POINTERS
- // We read the full pointer value and then decompress it in order to avoid
- // dealing with potential endianness issues.
- value = I::DecompressTaggedField(embedder_data, static_cast<uint32_t>(value));
+ // The tagged payload lives in the low kTaggedSize half of the slot (at
+ // kTaggedPayloadOffset == 0). Read it as a 32-bit field so the correct half
+ // is picked on both little and big endian targets. A full-width read plus
+ // truncation would return the CppHeap pointer half on big endian.
+ uint32_t compressed = I::ReadRawField<uint32_t>(embedder_data, value_offset);
+ A value = I::DecompressTaggedField(embedder_data, compressed);
+#else
+ A value = I::ReadRawField<A>(embedder_data, value_offset);
#endif
auto* isolate = I::GetCurrentIsolate();
diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h
index 1ffa08a0251..59dfe7b92c1 100644
--- a/deps/v8/include/v8-debug.h
+++ b/deps/v8/include/v8-debug.h
@@ -109,6 +109,12 @@ class V8_EXPORT StackFrame {
* Returns whether or not the associated function is defined by the user.
*/
bool IsUserJavaScript() const;
+
+ /**
+ * Returns whether the script was compiled with resource_is_opaque set in its
+ * ScriptOrigin.
+ */
+ bool IsScriptOpaque() const;
};
/**
diff --git a/deps/v8/include/v8-fast-api-calls.h b/deps/v8/include/v8-fast-api-calls.h
index 42d9f61518d..05486768e48 100644
--- a/deps/v8/include/v8-fast-api-calls.h
+++ b/deps/v8/include/v8-fast-api-calls.h
@@ -466,7 +466,15 @@ struct FastApiCallbackOptions {
/**
* The `data` passed to the FunctionTemplate constructor, or `undefined`.
*/
+ V8_DEPRECATE_SOON("Use DataV2 instead")
v8::Local<v8::Value> data;
+
+ /**
+ * The `data` passed to the FunctionTemplate constructor as `v8::Data`.
+ */
+ START_ALLOW_USE_DEPRECATED()
+ V8_INLINE v8::Local<v8::Data> DataV2() const { return data; }
+ END_ALLOW_USE_DEPRECATED()
};
namespace internal {
diff --git a/deps/v8/include/v8-function-callback.h b/deps/v8/include/v8-function-callback.h
index e0708430f61..de42be06391 100644
--- a/deps/v8/include/v8-function-callback.h
+++ b/deps/v8/include/v8-function-callback.h
@@ -35,6 +35,8 @@ class ConsoleCallArguments;
namespace api_internal {
V8_EXPORT v8::Local<v8::Value> GetFunctionTemplateData(
v8::Isolate* isolate, v8::Local<v8::Data> raw_target);
+V8_EXPORT v8::Local<v8::Data> GetFunctionTemplateDataV2(
+ v8::Isolate* isolate, v8::Local<v8::Data> raw_target);
} // namespace api_internal
template <typename T>
@@ -134,7 +136,10 @@ class FunctionCallbackInfo {
/** Indicates whether this is a regular call or a construct call. */
V8_INLINE bool IsConstructCall() const;
/** The data argument specified when creating the callback. */
+ V8_DEPRECATE_SOON("Use DataV2 instead")
V8_INLINE Local<Value> Data() const;
+ /** The data argument specified when creating the callback as `v8::Data`. */
+ V8_INLINE Local<v8::Data> DataV2() const;
/** The current Isolate. */
V8_INLINE Isolate* GetIsolate() const;
/** The ReturnValue for the call. */
@@ -233,8 +238,14 @@ class PropertyCallbackInfo {
* `NamedPropertyHandlerConfiguration` or
* `IndexedPropertyHandlerConfiguration.`
*/
+ V8_DEPRECATE_SOON("Use DataV2 instead")
V8_INLINE Local<Value> Data() const;
+ /**
+ * \return The data set in the callback configuration as `v8::Data`.
+ */
+ V8_INLINE Local<v8::Data> DataV2() const;
+
/**
* \return The object in the prototype chain of the receiver that has the
* interceptor. Suppose you have `x` and its prototype is `y`, and `y`
@@ -642,6 +653,12 @@ Local<Value> FunctionCallbackInfo<T>::Data() const {
return api_internal::GetFunctionTemplateData(GetIsolate(), target);
}
+template <typename T>
+Local<v8::Data> FunctionCallbackInfo<T>::DataV2() const {
+ auto target = Local<v8::Data>::FromSlot(&values_[kTargetIndex]);
+ return api_internal::GetFunctionTemplateDataV2(GetIsolate(), target);
+}
+
template <typename T>
Isolate* FunctionCallbackInfo<T>::GetIsolate() const {
return reinterpret_cast<Isolate*>(values_[kIsolateIndex]);
@@ -681,6 +698,14 @@ Local<Value> PropertyCallbackInfo<T>::Data() const {
return Local<Value>::New(GetIsolate(), data);
}
+template <typename T>
+Local<v8::Data> PropertyCallbackInfo<T>::DataV2() const {
+ internal::Address callback_info = args_[kCallbackInfoIndex];
+ internal::Address data =
+ I::ReadTaggedPointerField(callback_info, I::kCallbackInfoDataOffset);
+ return Local<v8::Data>::New(GetIsolate(), data);
+}
+
template <typename T>
Local<Object> PropertyCallbackInfo<T>::Holder() const {
return Local<Object>::FromSlot(&args_[kHolderIndex]);
diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h
index d2909b68851..2f80c9ff336 100644
--- a/deps/v8/include/v8-inspector.h
+++ b/deps/v8/include/v8-inspector.h
@@ -194,6 +194,8 @@ class V8_EXPORT V8InspectorSession {
virtual void breakProgram(StringView breakReason,
StringView breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
+ // Temporarily overrides the protocol setting without changing session state.
+ virtual void setSkipAllPausesForInternalUse(bool) = 0;
virtual void resume(bool setTerminateOnResume = false) = 0;
virtual void stepOver() = 0;
virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h
index 55d57d34255..5c20dc45827 100644
--- a/deps/v8/include/v8-internal.h
+++ b/deps/v8/include/v8-internal.h
@@ -223,6 +223,11 @@ using SandboxedPointer_t = Address;
// virtual address space for userspace. As such, limit the sandbox to 128GB (a
// quarter of the total available address space).
constexpr size_t kSandboxSizeLog2 = 37; // 128 GB
+#elif defined(V8_TARGET_ARCH_ARM64) && defined(V8_TARGET_OS_CHROMEOS)
+// On ARM64 ChromeOS, kernel config is 39 bits of virtual address space for
+// userspace, limit the sandbox to 128GB (a quarter of the total available
+// address space).
+constexpr size_t kSandboxSizeLog2 = 37; // 128 GB
#elif defined(V8_TARGET_OS_IOS)
// On iOS, we only get 64 GB of usable virtual address space even with the
// "jumbo" extended virtual addressing entitlement. Limit the sandbox size to
@@ -306,6 +311,9 @@ static_assert(kMaxSafeBufferSizeForSandbox <= kSandboxGuardRegionSize,
#if defined(V8_TARGET_OS_ANDROID)
// On Android, we often won't have sufficient virtual address space available.
constexpr size_t kAdditionalTrailingGuardRegionSize = 0;
+#elif defined(V8_TARGET_ARCH_ARM64) && defined(V8_TARGET_OS_CHROMEOS)
+// On ARM64 ChromeOS, kernel configs 39 bits of virtual address space.
+constexpr size_t kAdditionalTrailingGuardRegionSize = 0;
#elif defined(V8_TARGET_ARCH_LOONG64)
// Some hardwares like 2K3000 does not have sufficient virtual address space
// available.
@@ -467,14 +475,11 @@ constexpr size_t kMaxCppHeapPointers = 0;
//
// As an example, consider the following type hierarchy:
//
-// A
-// +-- B
-// | +-- C
-// | +-- D
-//. |
-// +-- E
-//
-// F
+// A F
+// / \
+// B E
+// / \
+// C D
//
// A potential type id assignment for range-based type checks is
// {A: 0, B: 1, C: 2, D: 3, E: 4, F: 5}. With that, the type check for type A
@@ -526,11 +531,7 @@ struct TagRange {
constexpr TagRange(Tag first, Tag last) : first(first), last(last) {
#ifdef V8_ENABLE_CHECKS
// This would typically be a DCHECK, but that's not available here.
-#if V8_HAS_BUILTIN_UNREACHABLE
if (first > last) __builtin_unreachable(); // Invalid tag range.
-#elif defined(_MSC_VER)
- if (first > last) __assume(0); // Invalid tag range.
-#endif
#endif
}
@@ -590,16 +591,7 @@ enum class ManagedTypeId : uint32_t {
kWasmFuncData,
kWasmManagedData,
kWasmNativeModule,
- kIcuBreakIterator,
kIcuBreakIteratorWithText,
- kIcuLocale,
- kIcuSimpleDateFormat,
- kIcuDateIntervalFormat,
- kIcuRelativeDateTimeFormatter,
- kIcuListFormatter,
- kIcuCollator,
- kIcuPluralRules,
- kIcuLocalizedNumberFormatter,
kTemporalDuration,
kTemporalInstant,
kTemporalPlainDate,
@@ -616,8 +608,17 @@ enum class ManagedTypeId : uint32_t {
#define SHARED_MANAGED_TAG_LIST(V) V(WasmFutexManagedObjectWaitListTag)
-#define MANAGED_TAG_LIST(V) \
- SHARED_MANAGED_TAG_LIST(V)
+#define MANAGED_TAG_LIST(V) \
+ SHARED_MANAGED_TAG_LIST(V) \
+ V(IcuBreakIteratorTag) \
+ V(IcuListFormatterTag) \
+ V(IcuLocaleTag) \
+ V(IcuSimpleDateFormatTag) \
+ V(IcuDateIntervalFormatTag) \
+ V(IcuRelativeDateTimeFormatterTag) \
+ V(IcuLocalizedNumberFormatterTag) \
+ V(IcuPluralRulesTag) \
+ V(IcuCollatorTag)
#define FOREIGN_TAG_LIST(V) \
V(GenericForeignTag) \
diff --git a/deps/v8/include/v8-isolate.h b/deps/v8/include/v8-isolate.h
index 50c87b78de5..a352b5f0164 100644
--- a/deps/v8/include/v8-isolate.h
+++ b/deps/v8/include/v8-isolate.h
@@ -669,6 +669,7 @@ class V8_EXPORT Isolate {
kModuleNamespaceMissingDefaultWithStarExport = 187,
kRegExpMatcherFlagsMismatch = 188,
kRegExpCustomSpecies = 189,
+ kWasmWideArithmetic = 190,
// 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
@@ -833,6 +834,12 @@ class V8_EXPORT Isolate {
void SetIsJSApiWrapperNativeErrorCallback(
IsJSApiWrapperNativeErrorCallback callback);
+ /**
+ * Set the callback invoked when an ArrayBuffer wrapping an embedder object
+ * is detached.
+ */
+ void SetArrayBufferDetachCallback(ArrayBufferDetachCallback callback);
+
/**
* This specifies the callback called when the stack property of Error
* is accessed.
@@ -995,6 +1002,7 @@ class V8_EXPORT Isolate {
* if any. Returns undefiend if no continuation preserved embedder data was
* set.
*/
+ V8_DEPRECATE_SOON("Use GetContinuationPreservedEmbedderData instead")
Local<Data> GetContinuationPreservedEmbedderDataV2();
/**
@@ -1002,6 +1010,7 @@ class V8_EXPORT Isolate {
* continuation runs. If `data` is empty, the continuation preserved embedder
* data is set to undefined.
*/
+ V8_DEPRECATE_SOON("Use SetContinuationPreservedEmbedderData instead")
void SetContinuationPreservedEmbedderDataV2(Local<Data> data);
/**
@@ -1256,8 +1265,7 @@ class V8_EXPORT Isolate {
void SetReleaseCppHeapCallbackForTesting(ReleaseCppHeapCallback callback);
/**
- * \returns the C++ heap managed by V8. Only available if such a heap has been
- * attached using `AttachCppHeap()`.
+ * \returns the C++ heap managed by V8.
*/
CppHeap* GetCppHeap() const;
diff --git a/deps/v8/include/v8-microtask-queue.h b/deps/v8/include/v8-microtask-queue.h
index de58638c85d..14ea13442a2 100644
--- a/deps/v8/include/v8-microtask-queue.h
+++ b/deps/v8/include/v8-microtask-queue.h
@@ -106,6 +106,18 @@ class V8_EXPORT MicrotaskQueue : public cppgc::GarbageCollected<MicrotaskQueue>,
*/
virtual int GetMicrotasksScopeDepth() const = 0;
+ /**
+ * Controls how microtasks in this queue are invoked. This is the per-queue
+ * counterpart of Isolate::SetMicrotasksPolicy(), which only affects the
+ * isolate's default queue; the initial value is the policy passed to New().
+ */
+ virtual void SetMicrotasksPolicy(MicrotasksPolicy policy) = 0;
+
+ /**
+ * Returns the policy controlling how microtasks in this queue are invoked.
+ */
+ virtual MicrotasksPolicy GetMicrotasksPolicy() const = 0;
+
MicrotaskQueue(const MicrotaskQueue&) = delete;
MicrotaskQueue& operator=(const MicrotaskQueue&) = delete;
diff --git a/deps/v8/include/v8-object.h b/deps/v8/include/v8-object.h
index 1dd2eb91124..f7fbd4e1302 100644
--- a/deps/v8/include/v8-object.h
+++ b/deps/v8/include/v8-object.h
@@ -926,11 +926,15 @@ Local<Data> Object::GetInternalField(int index) {
if (I::CanHaveInternalField(instance_type)) {
int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
(I::kEmbedderDataSlotSize * index);
- A value = I::ReadRawField<A>(obj, offset);
#ifdef V8_COMPRESS_POINTERS
- // We read the full pointer value and then decompress it in order to avoid
- // dealing with potential endianness issues.
- value = I::DecompressTaggedField(obj, static_cast<uint32_t>(value));
+ // The tagged payload lives in the low kTaggedSize half of the slot (at
+ // kTaggedPayloadOffset == 0). Read it as a 32-bit field so the correct half
+ // is picked on both little and big endian targets. A full width read plus
+ // truncation would return the CppHeap pointer half on big endian.
+ uint32_t compressed = I::ReadRawField<uint32_t>(obj, offset);
+ A value = I::DecompressTaggedField(obj, compressed);
+#else
+ A value = I::ReadRawField<A>(obj, offset);
#endif
auto* isolate = I::GetCurrentIsolate();
diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h
index 82769a8dfb4..df60fd7f66d 100644
--- a/deps/v8/include/v8-profiler.h
+++ b/deps/v8/include/v8-profiler.h
@@ -836,6 +836,11 @@ class V8_EXPORT AllocationProfile {
* been collected by GC.
*/
bool is_live;
+
+ /**
+ * Sample interval in bytes used when this sample was selected.
+ */
+ uint64_t sample_interval;
};
/**
@@ -1257,6 +1262,22 @@ class V8_EXPORT HeapProfiler {
*/
void StopSamplingHeapProfiler();
+ /**
+ * Updates the sampling interval for a currently running sampling heap
+ * profiler. The new interval is used for future sample scheduling.
+ *
+ * No-op if the sampling heap profiler is not running.
+ */
+ void SetSamplingHeapProfilerInterval(uint64_t sample_interval);
+
+ /**
+ * Returns the currently retained allocation samples without materializing
+ * the full allocation profile tree.
+ *
+ * Returns an empty vector if the sampling heap profiler is not running.
+ */
+ std::vector<AllocationProfile::Sample> GetSamplingHeapProfilerSamples();
+
/**
* Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is
diff --git a/deps/v8/include/v8-sandbox.h b/deps/v8/include/v8-sandbox.h
index 2cda25eb958..31d18d625e4 100644
--- a/deps/v8/include/v8-sandbox.h
+++ b/deps/v8/include/v8-sandbox.h
@@ -29,7 +29,9 @@ enum class CppHeapPointerTag : uint16_t {
kFirstTag = 0,
kNullTag = 0,
+ // Subtypes of v8::Object::Wrappable [0x0001 .. 0x6fff]
kFirstObjectWrappableTag = 1,
+ kFirstEmbedderWrappableTag = kFirstObjectWrappableTag,
/**
* The lower type ids are reserved for the embedder to assign. For that, the
@@ -54,24 +56,33 @@ enum class CppHeapPointerTag : uint16_t {
* the type check to use even fewer instructions (essentially replace a AND +
* SUB with a single AND).
*/
+ kLastEmbedderWrappableTag = 0x6eff,
- kFirstV8InternalTag = 0x6000,
- // V8-internal Oilpan objects that use v8::Object::Wrap() should go here.
- kTagForTesting,
- kInspectorV8ConsoleTag,
- kInspectorTaskInfoTag,
- kMicrotaskQueueTag,
- kWasmMemoryMapDescriptorTag,
- kCppGCManagedTag,
- kEmbedderDataSlotTag,
- kLastV8InternalTag,
+ // V8-internal Oilpan objects that inherit from v8::Object::Wrappable.
+ kFirstV8InternalWrappableTag = 0x6f00,
+ // Kept temporarily for backwards compatibility with Chromium's
+ // wrapper_type_info.h across the V8 roll.
+ kFirstV8InternalTag = kFirstV8InternalWrappableTag,
+ kLastV8InternalWrappableTag = 0x6fff,
+
+ kLastObjectWrappableTag = kLastV8InternalWrappableTag,
+
+ // Non-v8::Object::Wrappable CppHeap objects [0x7000 .. 0x7ffc]
+ kFirstNonWrappableTag = 0x7000,
+
+ kFirstV8InternalNonWrappableTag = kFirstNonWrappableTag,
+ kLastV8InternalNonWrappableTag = 0x70ff,
+
+ kFirstEmbedderNonWrappableTag = 0x7100,
+ kLastEmbedderNonWrappableTag = 0x7ffc,
+
+ kLastNonWrappableTag = kLastEmbedderNonWrappableTag,
#if !V8_ENABLE_SANDBOX
// Embedders that use the sandbox should use specific tags for each type.
- kDefaultTag,
+ kDefaultTag = kFirstEmbedderWrappableTag,
#endif // !V8_ENABLE_SANDBOX
- kLastObjectWrappableTag = 0x7ffc,
kZappedEntryTag = 0x7ffd,
kEvacuationEntryTag = 0x7ffe,
kFreeEntryTag = 0x7fff,
@@ -79,9 +90,6 @@ enum class CppHeapPointerTag : uint16_t {
kLastTag = 0x7fff,
};
-static_assert(static_cast<uint16_t>(CppHeapPointerTag::kLastV8InternalTag) <
- static_cast<uint16_t>(CppHeapPointerTag::kZappedEntryTag));
-
using CppHeapPointerTagRange = internal::TagRange<CppHeapPointerTag>;
constexpr CppHeapPointerTagRange kAnyCppHeapPointer(
@@ -95,12 +103,26 @@ constexpr CppHeapPointerTagRange kObjectWrappableTagRange(
CppHeapPointerTag::kFirstObjectWrappableTag,
CppHeapPointerTag::kLastObjectWrappableTag);
-constexpr CppHeapPointerTagRange kV8InternalTagRange(
- CppHeapPointerTag::kFirstV8InternalTag,
- CppHeapPointerTag::kLastV8InternalTag);
-
-static_assert(kObjectWrappableTagRange.Contains(kV8InternalTagRange),
- "V8Internal tag range must be within kObjectWrappableTagRange");
+// The tag range that embedders can use for their own types that inherit from
+// v8::Object::Wrappable.
+constexpr CppHeapPointerTagRange kEmbedderWrappableTagRange(
+ CppHeapPointerTag::kFirstEmbedderWrappableTag,
+ CppHeapPointerTag::kLastEmbedderWrappableTag);
+
+// The tag range for all non-v8::Object::Wrappable CppHeap objects, both
+// V8-internal and embedder-owned.
+constexpr CppHeapPointerTagRange kNonWrappableTagRange(
+ CppHeapPointerTag::kFirstNonWrappableTag,
+ CppHeapPointerTag::kLastNonWrappableTag);
+
+// The tag range that embedders can use for their own types that do not inherit
+// from v8::Object::Wrappable.
+constexpr CppHeapPointerTagRange kEmbedderNonWrappableTagRange(
+ CppHeapPointerTag::kFirstEmbedderNonWrappableTag,
+ CppHeapPointerTag::kLastEmbedderNonWrappableTag);
+
+static_assert(kObjectWrappableTagRange.Contains(kEmbedderWrappableTagRange));
+static_assert(kNonWrappableTagRange.Contains(kEmbedderNonWrappableTagRange));
/**
* Hardware support for the V8 Sandbox.
diff --git a/deps/v8/include/v8-script.h b/deps/v8/include/v8-script.h
index c6b0585cb11..3a67e56cb49 100644
--- a/deps/v8/include/v8-script.h
+++ b/deps/v8/include/v8-script.h
@@ -928,16 +928,17 @@ class V8_EXPORT ScriptCompiler {
Local<String> full_source_string, const ScriptOrigin& origin);
/**
- * Return a version tag for CachedData for the current V8 version & flags.
+ * Return a version tag for CachedData for the current V8 version, embedder
+ * version string, and flags.
*
* This value is meant only for determining whether a previously generated
* CachedData instance is still valid; the tag has no other meaing.
*
* Background: The data carried by CachedData may depend on the exact
- * V8 version number or current compiler flags. This means that when
- * persisting CachedData, the embedder must take care to not pass in
- * data from another V8 version, or the same version with different
- * features enabled.
+ * V8 version number, embedder version string, or current compiler flags.
+ * This means that when persisting CachedData, the embedder must take care
+ * to not pass in data from another V8 build, or the same build with
+ * different features enabled.
*
* The easiest way to do so is to clear the embedder's cache on any
* such change.
diff --git a/deps/v8/include/v8-traced-handle.h b/deps/v8/include/v8-traced-handle.h
index 3eb8e7835d7..72649e112e8 100644
--- a/deps/v8/include/v8-traced-handle.h
+++ b/deps/v8/include/v8-traced-handle.h
@@ -82,9 +82,10 @@ class TracedReferenceBase : public api_internal::IndirectHandleBase {
/**
* Update this reference in a thread-safe way.
*/
- void SetSlotThreadSafe(internal::Address* new_val) {
- reinterpret_cast<std::atomic<internal::Address*>*>(&slot())->store(
- new_val, std::memory_order_relaxed);
+ void SetSlotThreadSafe(internal::Address* new_val,
+ std::memory_order order = std::memory_order_relaxed) {
+ reinterpret_cast<std::atomic<internal::Address*>*>(&slot())->store(new_val,
+ order);
}
/**
@@ -185,10 +186,12 @@ class TracedReference : public BasicTracedReference<T> {
if (V8_UNLIKELY(that.IsEmpty())) {
return;
}
- this->slot() = this->NewFromNonEmptyValue(
- isolate, *that, &this->slot(),
- internal::TracedReferenceStoreMode::kInitializingStore,
- internal::TracedReferenceHandling::kDefault);
+ this->SetSlotThreadSafe(
+ this->NewFromNonEmptyValue(
+ isolate, *that, &this->slot(),
+ internal::TracedReferenceStoreMode::kInitializingStore,
+ internal::TracedReferenceHandling::kDefault),
+ std::memory_order_release);
}
/**
@@ -206,10 +209,12 @@ class TracedReference : public BasicTracedReference<T> {
if (V8_UNLIKELY(that.IsEmpty())) {
return;
}
- this->slot() = this->NewFromNonEmptyValue(
- isolate, *that, &this->slot(),
- internal::TracedReferenceStoreMode::kInitializingStore,
- internal::TracedReferenceHandling::kDroppable);
+ this->SetSlotThreadSafe(
+ this->NewFromNonEmptyValue(
+ isolate, *that, &this->slot(),
+ internal::TracedReferenceStoreMode::kInitializingStore,
+ internal::TracedReferenceHandling::kDroppable),
+ std::memory_order_release);
}
/**
@@ -356,10 +361,12 @@ void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) {
if (V8_UNLIKELY(other.IsEmpty())) {
return;
}
- this->SetSlotThreadSafe(this->NewFromNonEmptyValue(
- isolate, *other, &this->slot(),
- internal::TracedReferenceStoreMode::kAssigningStore,
- internal::TracedReferenceHandling::kDefault));
+ this->SetSlotThreadSafe(
+ this->NewFromNonEmptyValue(
+ isolate, *other, &this->slot(),
+ internal::TracedReferenceStoreMode::kAssigningStore,
+ internal::TracedReferenceHandling::kDefault),
+ std::memory_order_release);
}
template <class T>
@@ -371,10 +378,12 @@ void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other,
if (V8_UNLIKELY(other.IsEmpty())) {
return;
}
- this->SetSlotThreadSafe(this->NewFromNonEmptyValue(
- isolate, *other, &this->slot(),
- internal::TracedReferenceStoreMode::kAssigningStore,
- internal::TracedReferenceHandling::kDroppable));
+ this->SetSlotThreadSafe(
+ this->NewFromNonEmptyValue(
+ isolate, *other, &this->slot(),
+ internal::TracedReferenceStoreMode::kAssigningStore,
+ internal::TracedReferenceHandling::kDroppable),
+ std::memory_order_release);
}
template <class T>
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index 9af8a12370f..d47b8f7f5c8 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 15
-#define V8_MINOR_VERSION 5
-#define V8_BUILD_NUMBER 35
-#define V8_PATCH_LEVEL 22
+#define V8_MINOR_VERSION 6
+#define V8_BUILD_NUMBER 75
+#define V8_PATCH_LEVEL 13
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/include/v8-wasm.h b/deps/v8/include/v8-wasm.h
index 4d0158bd29d..17227e6d485 100644
--- a/deps/v8/include/v8-wasm.h
+++ b/deps/v8/include/v8-wasm.h
@@ -247,7 +247,7 @@ class V8_EXPORT WasmStreaming final {
* unpack the {CppGCManaged} itself.
*/
static std::shared_ptr<WasmStreaming> Unpack(Isolate* isolate,
- Local<Value> value);
+ Local<Data> data);
private:
std::unique_ptr<WasmStreamingImpl> impl_;
diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h
index 1e2d7c5658c..b7aeeade6b8 100644
--- a/deps/v8/include/v8config.h
+++ b/deps/v8/include/v8config.h
@@ -609,15 +609,11 @@ path. Add it with -I<path> to the command line
// functions.
// Use like:
// V8_NOINLINE V8_PRESERVE_MOST void UnlikelyMethod();
-#if V8_OS_WIN
-# define V8_PRESERVE_MOST
-#else
#if V8_HAS_ATTRIBUTE_PRESERVE_MOST
# define V8_PRESERVE_MOST __attribute__((preserve_most))
#else
# define V8_PRESERVE_MOST /* NOT SUPPORTED */
#endif
-#endif
// A macro (V8_DEPRECATED) to mark classes or functions as deprecated.
diff --git a/deps/v8/infra/mb/mb_config.pyl b/deps/v8/infra/mb/mb_config.pyl
index 0efde3556e7..3102eaf1ee5 100644
--- a/deps/v8/infra/mb/mb_config.pyl
+++ b/deps/v8/infra/mb/mb_config.pyl
@@ -653,7 +653,8 @@
'release_bot', 'x64', 'v8_dumpling'],
'release_x64_fuzzilli': [
'release_bot', 'x64', 'dcheck_always_on', 'v8_enable_slow_dchecks',
- 'v8_verify_heap', 'v8_verify_csa', 'fuzzilli'],
+ 'backtrace', 'trace_pc_guard', 'v8_enable_fuzzilli',
+ 'v8_enable_verification_features'],
'release_x64_gcmole': [
'release_bot', 'x64', 'gcmole'],
'release_x64_correctness_fuzzer_undefined_double' : [
@@ -954,11 +955,6 @@
'gn_args': 'target_os="fuchsia"',
},
- 'fuzzilli': {
- 'gn_args': 'v8_static_library=true v8_enable_v8_checks=true '
- 'sanitizer_coverage_flags="trace-pc-guard" v8_fuzzilli=true',
- },
-
'gcc': {
'gn_args': 'is_clang=false',
},
@@ -1217,6 +1213,10 @@
'gn_args': 'v8_enable_undefined_double=true',
},
+ 'v8_enable_verification_features': {
+ 'gn_args': 'v8_enable_verification_features=true',
+ },
+
'v8_enable_verify_predictable': {
'gn_args': 'v8_enable_verify_predictable=true',
},
diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl
index c7ea3073b91..cbc84e4984c 100644
--- a/deps/v8/infra/testing/builders.pyl
+++ b/deps/v8/infra/testing/builders.pyl
@@ -332,7 +332,8 @@
{'name': 'v8testing', 'shards': 7},
{'name': 'benchmarks', 'shards': 5},
{'name': 'mozilla', 'shards': 5},
- {'name': 'test262', 'shards': 12},
+ {'name': 'test262', 'variant': 'default', 'shards': 6},
+ {'name': 'test262', 'variant': 'future', 'shards': 6},
],
},
'v8_linux64_dbg': {
@@ -445,8 +446,9 @@
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
},
- # TODO(almuthanna): Add a new test config for the fuzzilli suite.
- 'tests': [],
+ 'tests': [
+ {'name': 'mjsunit', 'variant': 'default'},
+ ],
},
'v8_linux64_fyi_rel': {
'swarming_dimensions' : {
@@ -1408,6 +1410,14 @@
},
],
},
+ 'V8 Linux64 - Fuzzilli': {
+ 'swarming_dimensions' : {
+ 'os': 'Ubuntu-22.04',
+ },
+ 'tests': [
+ {'name': 'mjsunit', 'variant': 'default'},
+ ],
+ },
'V8 Linux64 - official': {
'swarming_dimensions' : {
'cpu': 'x86-64-avx2',
@@ -1831,7 +1841,8 @@
{'name': 'v8testing', 'shards': 7},
{'name': 'benchmarks', 'shards': 5},
{'name': 'mozilla', 'shards': 5},
- {'name': 'test262', 'shards': 16},
+ {'name': 'test262', 'variant': 'default', 'shards': 4},
+ {'name': 'test262', 'variant': 'future', 'shards': 4},
],
},
'V8 Linux64 GC Stress - custom snapshot': {
@@ -2245,7 +2256,7 @@
},
'tests': [
{'name': 'mozilla', 'shards': 3},
- {'name': 'test262', 'variant': 'default', 'shards': 3},
+ {'name': 'test262', 'variant': 'default', 'shards': 6},
{'name': 'v8testing', 'shards': 10},
{'name': 'v8testing', 'variant': 'extra', 'shards': 9},
{'name': 'v8testing', 'variant': 'turbolev', 'shards': 2},
@@ -2337,7 +2348,7 @@
},
'tests': [
{'name': 'mozilla', 'shards': 2},
- {'name': 'test262', 'variant': 'default', 'shards': 3},
+ {'name': 'test262', 'variant': 'default', 'shards': 6},
{'name': 'v8testing', 'shards': 12},
{'name': 'v8testing', 'variant': 'extra', 'shards': 14},
{
diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc
index adee19691fc..568671193c5 100644
--- a/deps/v8/src/api/api.cc
+++ b/deps/v8/src/api/api.cc
@@ -3542,6 +3542,10 @@ bool StackFrame::IsUserJavaScript() const {
return Utils::OpenDirectHandle(this)->script()->IsUserJavaScript();
}
+bool StackFrame::IsScriptOpaque() const {
+ return Utils::OpenDirectHandle(this)->script()->origin_options().IsOpaque();
+}
+
// --- J S O N ---
MaybeLocal<Value> JSON::Parse(Local<Context> context, Local<String> json_string,
@@ -4361,6 +4365,10 @@ size_t v8::BackingStore::ByteLength() const {
return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
}
+std::span<uint8_t> v8::BackingStore::ByteSpan() const {
+ return {static_cast<uint8_t*>(Data()), ByteLength()};
+}
+
size_t v8::BackingStore::MaxByteLength() const {
return reinterpret_cast<const i::BackingStore*>(this)->max_byte_length();
}
@@ -10497,15 +10505,15 @@ i::ValueHelper::InternalRepresentationType Isolate::GetDataFromSnapshotOnce(
return GetSerializedDataFromFixedArray(i_isolate, list, index);
}
-Local<Data> Isolate::GetContinuationPreservedEmbedderData() {
- return GetContinuationPreservedEmbedderDataV2();
+Local<Data> Isolate::GetContinuationPreservedEmbedderDataV2() {
+ return GetContinuationPreservedEmbedderData();
}
-void Isolate::SetContinuationPreservedEmbedderData(Local<Data> data) {
- SetContinuationPreservedEmbedderDataV2(data);
+void Isolate::SetContinuationPreservedEmbedderDataV2(Local<Data> data) {
+ SetContinuationPreservedEmbedderData(data);
}
-Local<Data> Isolate::GetContinuationPreservedEmbedderDataV2() {
+Local<Data> Isolate::GetContinuationPreservedEmbedderData() {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
return ToApiHandle<Data>(i::direct_handle(
@@ -10516,7 +10524,7 @@ Local<Data> Isolate::GetContinuationPreservedEmbedderDataV2() {
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
}
-void Isolate::SetContinuationPreservedEmbedderDataV2(Local<Data> data) {
+void Isolate::SetContinuationPreservedEmbedderData(Local<Data> data) {
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
if (data.IsEmpty()) {
@@ -11068,6 +11076,9 @@ CALLBACK_SETTER(IsJSApiWrapperNativeErrorCallback,
IsJSApiWrapperNativeErrorCallback,
is_js_api_wrapper_native_error_callback)
+CALLBACK_SETTER(ArrayBufferDetachCallback, ArrayBufferDetachCallback,
+ array_buffer_detach_callback)
+
void Isolate::InstallConditionalFeatures(Local<Context> context) {
v8::HandleScope handle_scope(this);
v8::Context::Scope context_scope(context);
@@ -12116,6 +12127,17 @@ void HeapProfiler::StopSamplingHeapProfiler() {
reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
}
+void HeapProfiler::SetSamplingHeapProfilerInterval(uint64_t sample_interval) {
+ reinterpret_cast<i::HeapProfiler*>(this)->SetSamplingHeapProfilerInterval(
+ sample_interval);
+}
+
+std::vector<AllocationProfile::Sample>
+HeapProfiler::GetSamplingHeapProfilerSamples() {
+ return reinterpret_cast<i::HeapProfiler*>(this)
+ ->GetSamplingHeapProfilerSamples();
+}
+
AllocationProfile* HeapProfiler::GetAllocationProfile() {
return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
}
@@ -12204,29 +12226,41 @@ const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
}
namespace api_internal {
-V8_EXPORT v8::Local<v8::Value> GetFunctionTemplateData(
- v8::Isolate* isolate, v8::Local<v8::Data> raw_target) {
+namespace {
+i::DirectHandle<i::Object> GetFunctionTemplateDataImpl(
+ v8::Isolate* isolate, v8::Local<v8::Data> raw_target,
+ const char* location) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::DirectHandle<i::Object> target = Utils::OpenDirectHandle(*raw_target);
if (i::IsFunctionTemplateInfo(*target)) {
- i::DirectHandle<i::Object> data(
+ return i::DirectHandle<i::Object>(
i::Cast<i::FunctionTemplateInfo>(*target)->callback_data(kAcquireLoad),
i_isolate);
- return Utils::ToLocal(data);
-
- } else if (i::IsJSFunction(*target)) {
+ }
+ if (i::IsJSFunction(*target)) {
i::DirectHandle<i::JSFunction> target_func = i::Cast<i::JSFunction>(target);
auto shared = target_func->shared();
if (shared->IsApiFunction()) {
- i::DirectHandle<i::Object> data(
+ return i::DirectHandle<i::Object>(
shared->api_func_data()->callback_data(kAcquireLoad), i_isolate);
- return Utils::ToLocal(data);
}
}
- Utils::ApiCheck(false, "api_internal::GetFunctionTemplateData",
- "Target function is not an Api function");
+ Utils::ApiCheck(false, location, "Target function is not an Api function");
UNREACHABLE();
}
+} // namespace
+
+V8_EXPORT v8::Local<v8::Value> GetFunctionTemplateData(
+ v8::Isolate* isolate, v8::Local<v8::Data> raw_target) {
+ return Utils::ToLocal(GetFunctionTemplateDataImpl(
+ isolate, raw_target, "api_internal::GetFunctionTemplateData"));
+}
+
+V8_EXPORT v8::Local<v8::Data> GetFunctionTemplateDataV2(
+ v8::Isolate* isolate, v8::Local<v8::Data> raw_target) {
+ return ToApiHandle<Data>(GetFunctionTemplateDataImpl(
+ isolate, raw_target, "api_internal::GetFunctionTemplateDataV2"));
+}
} // namespace api_internal
RegisterState::RegisterState()
@@ -12288,7 +12322,7 @@ void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
// static
std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* v8_isolate,
- Local<Value> value) {
+ Local<Data> data) {
FATAL("WebAssembly is disabled");
}
#endif // !V8_ENABLE_WEBASSEMBLY
@@ -12518,7 +12552,7 @@ bool ValidateFunctionCallbackInfo(const FunctionCallbackInfo<T>& info) {
CHECK_EQ(i_isolate, Isolate::Current());
CHECK(!i_isolate->GetIncumbentContext().is_null());
CHECK(info.This()->IsObject());
- CHECK(!info.Data().IsEmpty());
+ CHECK(!info.DataV2().IsEmpty());
CHECK(info.GetReturnValue().Get()->IsValue());
return true;
}
@@ -12535,7 +12569,7 @@ bool ValidatePropertyCallbackInfo(const PropertyCallbackInfo<T>& info) {
*i::PropertyCallbackArguments::GetPropertyName(info);
CHECK(i::IsName(name));
}
- CHECK(info.Data()->IsValue());
+ CHECK(info.DataV2()->IsValue());
USE(info.ShouldThrowOnError());
if (!std::is_same_v<T, void>) {
CHECK(info.GetReturnValue().Get()->IsValue());
diff --git a/deps/v8/src/ast/ast-value-factory.cc b/deps/v8/src/ast/ast-value-factory.cc
index ed113acbd63..0e2f6268b55 100644
--- a/deps/v8/src/ast/ast-value-factory.cc
+++ b/deps/v8/src/ast/ast-value-factory.cc
@@ -29,6 +29,7 @@
#include "src/base/hashmap-entry.h"
#include "src/base/logging.h"
+#include "src/base/small-vector.h"
#include "src/common/globals.h"
#include "src/heap/factory-inl.h"
#include "src/heap/local-factory-inl.h"
@@ -82,6 +83,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
// The StringHasher will set up the hash. Bail out early if we know it
// can't be convertible to an array index.
if (!IsIntegerIndex()) return false;
+ DCHECK(is_one_byte());
if (length() <= Name::kMaxCachedArrayIndexLength) {
*index = StringHasher::DecodeArrayIndexFromHashField(
raw_hash_field_, HashSeed(GetReadOnlyRoots()));
@@ -340,6 +342,7 @@ const AstRawString* AstValueFactory::GetOneByteStringInternal(
const AstRawString* AstValueFactory::GetTwoByteStringInternal(
base::Vector<const uint16_t> literal) {
+ DCHECK(!String::IsOneByte(literal.begin(), literal.length()));
uint32_t raw_hash_field = StringHasher::HashSequentialString<uint16_t>(
literal.begin(), literal.length(), hash_seed_);
return GetString(raw_hash_field, false,
@@ -349,16 +352,20 @@ const AstRawString* AstValueFactory::GetTwoByteStringInternal(
const AstRawString* AstValueFactory::GetString(
Tagged<String> literal,
const SharedStringAccessGuardIfNeeded& access_guard) {
- const AstRawString* result = nullptr;
DisallowGarbageCollection no_gc;
String::FlatContent content = literal->GetFlatContent(no_gc, access_guard);
if (content.IsOneByte()) {
- result = GetOneByteStringInternal(content.ToOneByteVector());
- } else {
- DCHECK(content.IsTwoByte());
- result = GetTwoByteStringInternal(content.ToUC16Vector());
+ return GetOneByteStringInternal(content.ToOneByteVector());
}
- return result;
+ DCHECK(content.IsTwoByte());
+ base::Vector<const uint16_t> vector = content.ToUC16Vector();
+ if (String::IsOneByte(vector.begin(), vector.length())) {
+ base::SmallVector<uint8_t, 64> one_byte(vector.length());
+ CopyChars(one_byte.data(), vector.begin(), vector.length());
+ return GetOneByteStringInternal(
+ base::Vector<const uint8_t>(one_byte.data(), vector.length()));
+ }
+ return GetTwoByteStringInternal(vector);
}
AstConsString* AstValueFactory::NewConsString() {
diff --git a/deps/v8/src/ast/ast-value-factory.h b/deps/v8/src/ast/ast-value-factory.h
index 5ca83bc76f2..23b37a9e2e8 100644
--- a/deps/v8/src/ast/ast-value-factory.h
+++ b/deps/v8/src/ast/ast-value-factory.h
@@ -63,7 +63,7 @@ class AstRawString final : public ZoneObject {
return is_one_byte() ? literal_bytes_.length()
: literal_bytes_.length() / 2;
}
- bool AsArrayIndex(uint32_t* index) const;
+ V8_EXPORT_PRIVATE bool AsArrayIndex(uint32_t* index) const;
bool IsIntegerIndex() const;
V8_EXPORT_PRIVATE bool IsOneByteEqualTo(const char* data) const;
V8_EXPORT_PRIVATE uint16_t FirstCharacter() const;
@@ -383,8 +383,8 @@ class AstValueFactory {
const AstRawString* GetTwoByteString(base::Vector<const uint16_t> literal) {
return GetTwoByteStringInternal(literal);
}
- const AstRawString* GetString(Tagged<String> literal,
- const SharedStringAccessGuardIfNeeded&);
+ V8_EXPORT_PRIVATE const AstRawString* GetString(
+ Tagged<String> literal, const SharedStringAccessGuardIfNeeded&);
V8_EXPORT_PRIVATE AstConsString* NewConsString();
V8_EXPORT_PRIVATE AstConsString* NewConsString(const AstRawString* str);
diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h
index 21ed80e6a4d..b036f590d04 100644
--- a/deps/v8/src/ast/ast.h
+++ b/deps/v8/src/ast/ast.h
@@ -1578,13 +1578,6 @@ class VariableProxy final : public Expression {
bit_field_ = IsNewTargetField::update(bit_field_, true);
}
- bool is_inside_try_catch() const {
- return IsInsideTryCatchField::decode(bit_field_);
- }
- void set_is_inside_try_catch() {
- bit_field_ = IsInsideTryCatchField::update(bit_field_, true);
- }
-
HoleCheckMode hole_check_mode() const {
HoleCheckMode mode = HoleCheckModeField::decode(bit_field_);
DCHECK_IMPLIES(mode == HoleCheckMode::kRequired,
@@ -1658,7 +1651,6 @@ class VariableProxy final : public Expression {
IsResolvedField::encode(false) |
IsRemovedFromUnresolvedField::encode(false) |
IsHomeObjectField::encode(false) |
- IsInsideTryCatchField::encode(false) |
HoleCheckModeField::encode(HoleCheckMode::kElided);
}
@@ -1669,8 +1661,7 @@ class VariableProxy final : public Expression {
using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
using IsHomeObjectField = IsNewTargetField::Next<bool, 1>;
- using IsInsideTryCatchField = IsHomeObjectField::Next<bool, 1>;
- using HoleCheckModeField = IsInsideTryCatchField::Next<HoleCheckMode, 1>;
+ using HoleCheckModeField = IsHomeObjectField::Next<HoleCheckMode, 1>;
union {
const AstRawString* raw_name_; // if !is_resolved_
diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc
index 59d8ca6bbbf..7713cd8103d 100644
--- a/deps/v8/src/ast/scopes.cc
+++ b/deps/v8/src/ast/scopes.cc
@@ -232,17 +232,18 @@ ClassScope::ClassScope(IsolateT* isolate, Zone* zone,
DCHECK_EQ(scope_info->ContextLocalInitFlag(index),
InitializationFlag::kNeedsInitialization);
DCHECK_EQ(scope_info->ContextLocalMaybeAssignedFlag(index),
- MaybeAssignedFlag::kNotAssigned);
+ MaybeAssignedFlag::kMaybeAssigned);
Variable* var = DeclareClassVariable(
ast_value_factory,
ast_value_factory->GetString(name,
SharedStringAccessGuardIfNeeded(isolate)),
scope_info->EndPosition());
+ var->set_maybe_assigned();
var->AllocateTo(VariableLocation::CONTEXT,
Context::MIN_CONTEXT_SLOTS + index);
}
- DCHECK(scope_info->HasPositionInfo());
+ DCHECK(!scope_info->IsEmpty());
set_start_position(scope_info->StartPosition());
set_end_position(scope_info->EndPosition());
}
@@ -265,7 +266,6 @@ Scope::Scope(Zone* zone, ScopeType scope_type,
already_resolved_ = true;
#endif
set_language_mode(scope_info->language_mode());
- DCHECK_EQ(ContextHeaderLength(), num_heap_slots_);
set_private_name_lookup_skips_outer_class(
scope_info->PrivateNameLookupSkipsOuterClass());
// We don't really need to use the preparsed scope data; this is just to
@@ -395,7 +395,7 @@ void Scope::SetDefaults() {
IsHoistedInContextField::encode(false);
num_stack_slots_ = 0;
- num_heap_slots_ = ContextHeaderLength();
+ num_heap_slots_ = 0;
set_language_mode(LanguageMode::kSloppy);
}
@@ -449,7 +449,6 @@ Scope* Scope::DeserializeScopeChain(
DeclarationScope* eval_scope =
zone->New<DeclarationScope>(zone, EVAL_SCOPE, ast_value_factory,
isolate->factory()->empty_scope_info());
- eval_scope->num_heap_slots_ = 0;
int position = script->eval_from_position();
eval_scope->set_start_position(position);
eval_scope->set_end_position(position);
@@ -473,10 +472,6 @@ Scope* Scope::DeserializeScopeChain(
continue;
}
- if (parse_info && IsGeneratorFunction(scope_info->function_kind())) {
- parse_info->set_has_generator_in_scope_chain();
- }
-
if (scope_info->scope_type() == FUNCTION_SCOPE) {
outer_scope = zone->New<DeclarationScope>(
zone, FUNCTION_SCOPE, ast_value_factory, handle(scope_info, isolate));
@@ -501,6 +496,7 @@ Scope* Scope::DeserializeScopeChain(
if (deserialization_mode == DeserializationMode::kIncludingVariables) {
script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
}
+ script_scope->num_heap_slots_ = scope_info->ContextLength();
script_scope->set_start_position(scope_info->StartPosition());
script_scope->set_end_position(scope_info->EndPosition());
DCHECK(!scope_info->HasOuterScopeInfo());
@@ -559,6 +555,7 @@ Scope* Scope::DeserializeScopeChain(
if (current_scope != nullptr) {
outer_scope->AddInnerScope(current_scope);
}
+ outer_scope->num_heap_slots_ = scope_info->ContextLength();
outer_scope->set_start_position(scope_info->StartPosition());
outer_scope->set_end_position(scope_info->EndPosition());
@@ -622,11 +619,6 @@ const DeclarationScope* Scope::AsDeclarationScope() const {
return static_cast<const DeclarationScope*>(this);
}
-FunctionKind Scope::scope_closure_function_kind() const {
- if (!scope_info_.is_null()) return scope_info_->function_kind();
- return GetClosureScope()->function_kind();
-}
-
ModuleScope* Scope::AsModuleScope() {
SBXCHECK(is_module_scope());
return static_cast<ModuleScope*>(this);
@@ -894,15 +886,16 @@ Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
if (cache == nullptr) {
DCHECK_NULL(function_);
cache = this;
- } else if (function_ != nullptr) {
- return function_;
}
DCHECK(this->IsOuterScopeOf(cache));
DCHECK_NULL(cache->variables_.Lookup(name));
- VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
- : NORMAL_VARIABLE;
- function_ = zone()->New<Variable>(this, name, VariableMode::kConst, kind,
- kCreatedInitialized);
+ if (function_ == nullptr) {
+ VariableKind kind = is_sloppy(language_mode())
+ ? SLOPPY_FUNCTION_NAME_VARIABLE
+ : NORMAL_VARIABLE;
+ function_ = zone()->New<Variable>(this, name, VariableMode::kConst, kind,
+ kCreatedInitialized);
+ }
if (sloppy_eval_can_extend_vars()) {
cache->NonLocal(name, VariableMode::kDynamic);
} else {
@@ -975,7 +968,7 @@ Scope* Scope::FinalizeBlockScope() {
!AsDeclarationScope()->sloppy_eval_can_extend_vars());
// This block does not need a context.
- num_heap_slots_ = 0;
+ DCHECK_EQ(0, num_heap_slots_);
// Mark scope as removed by making it its own sibling.
#ifdef DEBUG
@@ -1043,37 +1036,6 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
}
}
-void Scope::MarkUnresolvedVariablesAsInsideTryCatch() {
- // While proxy marking is generic, we only actually call this when nested in a
- // generator because that's the only place we care about variables escaping
- // try-catch blocks (for hole check elision and resume logic).
- for (VariableProxy* proxy : unresolved_list_) {
- proxy->set_is_inside_try_catch();
- }
- for (Scope* inner = inner_scope_; inner; inner = inner->sibling_) {
- if (inner->is_closure_scope()) continue;
- inner->MarkUnresolvedVariablesAsInsideTryCatch();
- }
-}
-
-void Scope::Snapshot::MarkUnresolvedVariablesAsInsideTryCatch() {
- // While proxy marking is generic, we only actually call this when nested in a
- // generator because that's the only place we care about variables escaping
- // try-catch blocks (for hole check elision and resume logic).
- auto it = top_unresolved_;
- auto end = outer_scope_->unresolved_list_.end();
-
- while (it != end) {
- (*it)->set_is_inside_try_catch();
- ++it;
- }
- for (Scope* inner = outer_scope_->inner_scope_; inner != top_inner_scope_;
- inner = inner->sibling_) {
- if (inner->is_closure_scope()) continue;
- inner->MarkUnresolvedVariablesAsInsideTryCatch();
- }
-}
-
Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
DCHECK(!scope_info_.is_null());
DCHECK(this->IsOuterScopeOf(cache));
@@ -1437,16 +1399,7 @@ Declaration* DeclarationScope::CheckConflictingVarDeclarations(
// anything, so we can't conflict with anything either. The one
// exception is the binding variable in catch scopes, which is handled
// by the if above.
- if (!IsLexicalVariableMode(other_var->mode())) {
- if (current->sloppy_eval_can_extend_vars()) {
- // See the comment for RemoveDynamic. In addition to removing
- // dynamic variables we also need to remove function_ since
- // otherwise we won't recreate a masking dynamic variable during
- // scope resolution, causing divergent compilation.
- current->AsDeclarationScope()->function_ = nullptr;
- }
- break;
- }
+ if (!IsLexicalVariableMode(other_var->mode())) break;
return decl;
}
current = current->outer_scope();
@@ -1612,18 +1565,6 @@ DeclarationScope* Scope::GetClosureScope() {
return scope->AsDeclarationScope();
}
-bool Scope::HasOuterGenerator() const {
- const Scope* scope = GetClosureScope()->outer_scope();
- while (scope != nullptr) {
- scope = scope->GetClosureScope();
- if (IsGeneratorFunction(scope->AsDeclarationScope()->function_kind())) {
- return true;
- }
- scope = scope->outer_scope();
- }
- return false;
-}
-
bool Scope::NeedsScopeInfo() const {
DCHECK(!already_resolved_);
DCHECK(GetClosureScope()->ShouldEagerCompile());
@@ -1779,7 +1720,7 @@ void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
}
} else {
var->set_is_used();
- UpdateVariableMaybeAssigned(var, proxy, scope);
+ if (proxy->is_assigned()) var->SetMaybeAssigned();
}
}
@@ -2535,36 +2476,11 @@ bool UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope,
} // anonymous namespace
-void Scope::UpdateVariableMaybeAssigned(Variable* var, VariableProxy* proxy,
- Scope* current_scope) {
- if (proxy->is_assigned()) {
- var->SetMaybeAssigned();
- return;
- }
-
- if (proxy->is_inside_try_catch()) {
- Variable* true_var = var;
- while (true_var->has_local_if_not_shadowed()) {
- true_var = true_var->local_if_not_shadowed();
- }
- if (!true_var->scope()->IsOuterScopeUpToClosureScopeOf(current_scope) &&
- IsGeneratorFunction(true_var->scope()->scope_closure_function_kind())) {
- // We treat variables captured by generator yields in a try-catch as
- // maybe_assigned since the context allocation and assignment might be
- // skipped when resuming from a yield.
- // See test/mjsunit/maglev/context-inverted-generator2.js.
- true_var->SetMaybeAssigned();
- }
- }
-}
-
void Scope::ResolveTo(VariableProxy* proxy, Variable* var,
int access_position) {
DCHECK_NOT_NULL(var);
UpdateNeedsHoleCheck(var, proxy, this, access_position);
proxy->BindTo(var);
-
- UpdateVariableMaybeAssigned(var, proxy, this);
}
void Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
@@ -2576,7 +2492,7 @@ void Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
var->set_is_used();
if (!var->is_dynamic()) {
var->ForceContextAllocation();
- UpdateVariableMaybeAssigned(var, proxy, scope);
+ if (proxy->is_assigned()) var->SetMaybeAssigned();
return;
}
}
@@ -2656,7 +2572,8 @@ void Scope::AllocateStackSlot(Variable* var) {
void Scope::AllocateHeapSlot(Variable* var) {
- var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
+ var->AllocateTo(VariableLocation::CONTEXT,
+ ContextHeaderLength() + num_heap_slots_++);
}
void DeclarationScope::AllocateParameterLocals() {
@@ -2840,10 +2757,7 @@ void Scope::AllocateVariablesRecursively() {
this->ForEach([](Scope* scope) -> Iteration {
DCHECK(!scope->already_resolved_);
if (WasLazilyParsed(scope)) return Iteration::kContinue;
- if (scope->sloppy_eval_can_extend_vars()) {
- scope->num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
- }
- DCHECK_EQ(scope->ContextHeaderLength(), scope->num_heap_slots_);
+ DCHECK_EQ(0, scope->num_heap_slots_);
// Allocate variables for this scope.
// Parameters must be allocated first, if any.
@@ -2855,24 +2769,11 @@ void Scope::AllocateVariablesRecursively() {
}
scope->AllocateNonParameterLocalsAndDeclaredGlobals();
- // Force allocation of a context for this scope if necessary. For a 'with'
- // scope and for a function scope that makes an 'eval' call we need a
- // context, even if no local variables were statically allocated in the
- // scope. Likewise for modules. Also force a context, if the scope is
- // stricter than the outer scope.
- bool must_have_context =
- scope->is_with_scope() || scope->is_module_scope() ||
- scope->ForceContextForLanguageMode() ||
- (scope->is_function_scope() &&
- scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()) ||
- (scope->is_block_scope() && scope->is_declaration_scope() &&
- scope->AsDeclarationScope()->sloppy_eval_can_extend_vars());
-
- // If we didn't allocate any locals in the local context, then we only
- // need the minimal number of slots if we must have a context.
- if (scope->num_heap_slots_ == scope->ContextHeaderLength() &&
- !must_have_context) {
- scope->num_heap_slots_ = 0;
+ // If we need a context, ensure num_heap_slots_ includes space for the
+ // context header.
+ if (scope->num_heap_slots_ > 0 || scope->HasContextExtensionSlot() ||
+ scope->ForceContextForLanguageMode()) {
+ scope->num_heap_slots_ += scope->ContextHeaderLength();
}
// If the number of context slots are over the function context threshold,
@@ -2882,9 +2783,6 @@ void Scope::AllocateVariablesRecursively() {
scope->set_has_context_cells(false);
}
- // Allocation done.
- DCHECK(scope->num_heap_slots_ == 0 ||
- scope->num_heap_slots_ >= scope->ContextHeaderLength());
return Iteration::kDescend;
});
}
@@ -2892,8 +2790,7 @@ void Scope::AllocateVariablesRecursively() {
template <typename IsolateT>
void Scope::AllocateScopeInfosRecursively(
IsolateT* isolate, MaybeHandle<ScopeInfo> outer_scope,
- std::unordered_map<int, IndirectHandle<ScopeInfo>>& scope_infos_to_reuse,
- FunctionKind closure_function_kind) {
+ std::unordered_map<int, IndirectHandle<ScopeInfo>>& scope_infos_to_reuse) {
DCHECK(scope_info_.is_null());
MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
@@ -2915,8 +2812,7 @@ void Scope::AllocateScopeInfosRecursively(
it->second = {};
#endif
} else if (NeedsScopeInfo()) {
- scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope,
- closure_function_kind);
+ scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
#ifdef DEBUG
// Mark this ID as being used.
scope_infos_to_reuse[UniqueIdInScript()] = {};
@@ -2940,12 +2836,8 @@ void Scope::AllocateScopeInfosRecursively(
}
if (!scope->is_function_scope() ||
scope->AsDeclarationScope()->ShouldEagerCompile()) {
- FunctionKind inner_closure_kind =
- scope->is_closure_scope()
- ? scope->AsDeclarationScope()->function_kind()
- : closure_function_kind;
- scope->AllocateScopeInfosRecursively(
- isolate, next_outer_scope, scope_infos_to_reuse, inner_closure_kind);
+ scope->AllocateScopeInfosRecursively(isolate, next_outer_scope,
+ scope_infos_to_reuse);
} else {
auto scope_it = scope_infos_to_reuse.find(scope->UniqueIdInScript());
if (scope_it != scope_infos_to_reuse.end()) {
@@ -2963,14 +2855,12 @@ template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Scope::
AllocateScopeInfosRecursively<Isolate>(
Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope,
std::unordered_map<int, IndirectHandle<ScopeInfo>>&
- scope_infos_to_reuse,
- FunctionKind closure_function_kind);
+ scope_infos_to_reuse);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Scope::
AllocateScopeInfosRecursively<LocalIsolate>(
LocalIsolate* isolate, MaybeHandle<ScopeInfo> outer_scope,
std::unordered_map<int, IndirectHandle<ScopeInfo>>&
- scope_infos_to_reuse,
- FunctionKind closure_function_kind);
+ scope_infos_to_reuse);
void DeclarationScope::RecalcPrivateNameContextChain() {
// The outermost scope in a class heritage expression is marked to skip the
@@ -3028,6 +2918,7 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
if (Scope* outer = scope->GetOuterScopeWithContext()) {
DCHECK((std::is_same_v<Isolate, v8::internal::Isolate>));
outer_scope = outer->scope_info_;
+ CHECK(!outer_scope.ToHandleChecked()->IsEmpty());
}
}
@@ -3054,7 +2945,7 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
Tagged<ScopeInfo> scope_info;
if (Is<SharedFunctionInfo>(info)) {
Tagged<SharedFunctionInfo> sfi = Cast<SharedFunctionInfo>(info);
- if (!sfi->scope_info()->IsEmpty()) {
+ if (sfi->HasScopeInfo()) {
scope_info = sfi->scope_info();
} else if (sfi->HasOuterScopeInfo()) {
scope_info = sfi->GetOuterScopeInfo();
@@ -3063,7 +2954,7 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
}
} else {
scope_info = Cast<ScopeInfo>(info);
- if (scope_info->IsEmpty()) continue;
+ DCHECK(!scope_info->IsEmpty());
}
while (true) {
if (scope_info == outer) break;
@@ -3179,25 +3070,16 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
}
}
- scope->AllocateScopeInfosRecursively(
- isolate, outer_scope, scope_infos_to_reuse,
- scope->GetClosureScope()->function_kind());
+ scope->AllocateScopeInfosRecursively(isolate, outer_scope,
+ scope_infos_to_reuse);
// The debugger expects all shared function infos to contain a scope info.
// Since the top-most scope will end up in a shared function info, make sure
// it has one, even if it doesn't need a scope info.
// TODO(yangguo): Remove this requirement.
if (scope->scope_info_.is_null()) {
- scope->scope_info_ = ScopeInfo::Create(isolate, scope->zone(), scope,
- outer_scope, scope->function_kind());
- }
-
- // Ensuring that the outer script scope has a scope info avoids having
- // special case for native contexts vs other contexts.
- if (parse_info->script_scope() &&
- parse_info->script_scope()->scope_info_.is_null()) {
- parse_info->script_scope()->scope_info_ =
- isolate->factory()->empty_scope_info();
+ scope->scope_info_ =
+ ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
}
}
diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h
index 5a7effdcafa..f85e7420968 100644
--- a/deps/v8/src/ast/scopes.h
+++ b/deps/v8/src/ast/scopes.h
@@ -121,10 +121,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// to REPL_GLOBAL. Should only be called on REPL scripts.
void RewriteReplGlobalVariables();
- // Mark all unresolved variables added after taking the snapshot as inside a
- // try/catch.
- void MarkUnresolvedVariablesAsInsideTryCatch();
-
class Snapshot final {
public:
inline explicit Snapshot(Scope* scope);
@@ -145,9 +141,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
}
void Reparent(DeclarationScope* new_parent);
- // Mark all unresolved variables added after taking the snapshot as inside a
- // try/catch.
- void MarkUnresolvedVariablesAsInsideTryCatch();
private:
Scope* outer_scope_;
@@ -580,12 +573,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
DeclarationScope* GetClosureScope();
const DeclarationScope* GetClosureScope() const;
- // Returns the function kind of the closure scope, even if the scope is fully
- // deserialized and its closure scope isn't available.
- FunctionKind scope_closure_function_kind() const;
-
- bool HasOuterGenerator() const;
-
// Returns true if this scope is an outer scope of the given scope, up to
// and including the closure scope of the given scope.
bool IsOuterScopeUpToClosureScopeOf(Scope* scope) const;
@@ -814,8 +801,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
bool force_context_allocation = false);
static void ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
Scope* end);
- static void UpdateVariableMaybeAssigned(Variable* var, VariableProxy* proxy,
- Scope* current_scope);
void ResolveTo(VariableProxy* proxy, Variable* var, int access_position);
void ResolveVariable(VariableProxy* proxy);
V8_WARN_UNUSED_RESULT bool ResolveVariablesRecursively(Scope* end);
@@ -846,8 +831,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
template <typename IsolateT>
void AllocateScopeInfosRecursively(
IsolateT* isolate, MaybeHandle<ScopeInfo> outer_scope,
- std::unordered_map<int, IndirectHandle<ScopeInfo>>& scope_infos_to_reuse,
- FunctionKind closure_function_kind);
+ std::unordered_map<int, IndirectHandle<ScopeInfo>>& scope_infos_to_reuse);
// Construct a scope based on the scope info.
Scope(Zone* zone, ScopeType type, AstValueFactory* ast_value_factory,
diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h
index 7c83c335718..342ac274076 100644
--- a/deps/v8/src/ast/variables.h
+++ b/deps/v8/src/ast/variables.h
@@ -93,6 +93,9 @@ class Variable final : public ZoneObject {
void clear_maybe_assigned() {
bit_field_ = MaybeAssignedFlagField::update(bit_field_, kNotAssigned);
}
+ void set_maybe_assigned() {
+ bit_field_ = MaybeAssignedFlagField::update(bit_field_, kMaybeAssigned);
+ }
void SetMaybeAssigned() {
if (IsImmutableLexicalVariableMode(mode())) {
return;
@@ -304,11 +307,13 @@ class Variable final : public ZoneObject {
}
// LINT.ThenChange(/src/debug/debug-scope-info.cc:VariableIsReceiver)
+ // LINT.IfChange(VariableIsExport)
bool IsExport() const {
DCHECK_EQ(location(), VariableLocation::MODULE);
DCHECK_NE(index(), 0);
return index() > 0;
}
+ // LINT.ThenChange(/src/debug/debug-scope-info.h:VariableIsExport)
void AllocateTo(VariableLocation location, int index) {
DCHECK(IsUnallocated() ||
@@ -355,10 +360,6 @@ class Variable final : public ZoneObject {
uint16_t bit_field_;
uint16_t hole_check_analysis_bit_field_;
- void set_maybe_assigned() {
- bit_field_ = MaybeAssignedFlagField::update(bit_field_, kMaybeAssigned);
- }
-
uint8_t HoleCheckBitmapIndex() const {
return HoleCheckBitmapIndexField::decode(hole_check_analysis_bit_field_);
}
diff --git a/deps/v8/src/base/cpu/cpu-x86.cc b/deps/v8/src/base/cpu/cpu-x86.cc
index 96ba25d15b2..c50ed8dabcb 100644
--- a/deps/v8/src/base/cpu/cpu-x86.cc
+++ b/deps/v8/src/base/cpu/cpu-x86.cc
@@ -133,7 +133,7 @@ void CPU::DetectFeatures() {
has_avx_ = (cpu_info[2] & 0x10000000) != 0;
has_avx2_ = (cpu_info70[1] & 0x00000020) != 0;
has_avx_vnni_ = (cpu_info71[0] & 0x00000010) != 0;
- has_avx_vnni_int8_ = (cpu_info71[3] & 0x00000020) != 0;
+ has_avx_vnni_int8_ = (cpu_info71[3] & 0x00000010) != 0;
has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
has_f16c_ = (cpu_info[2] & 0x20000000) != 0;
has_apx_f_ = (cpu_info71[3] & 0x00200000) != 0;
diff --git a/deps/v8/src/base/memcopy.h b/deps/v8/src/base/memcopy.h
index 51b285d95f0..4c2bea25979 100644
--- a/deps/v8/src/base/memcopy.h
+++ b/deps/v8/src/base/memcopy.h
@@ -5,7 +5,6 @@
#ifndef V8_BASE_MEMCOPY_H_
#define V8_BASE_MEMCOPY_H_
-#include <limits.h>
#include <stdlib.h>
#include <algorithm>
diff --git a/deps/v8/src/base/platform/platform-posix.cc b/deps/v8/src/base/platform/platform-posix.cc
index df122799fdc..7add12aa479 100644
--- a/deps/v8/src/base/platform/platform-posix.cc
+++ b/deps/v8/src/base/platform/platform-posix.cc
@@ -82,19 +82,7 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
-/*
- * NOTE: illumos starting with illumos#14418 (pushed April 20th, 2022)
- * prototypes madvise(3C) properly with a `void *` first argument.
- * The only way to detect this outside of configure-time checking is to
- * check for the existence of MEMCNTL_SHARED, which gets defined for the first
- * time in illumos#14418 under the same circumstances save _STRICT_POSIX, which
- * thankfully neither Solaris nor illumos builds of Node or V8 do.
- *
- * If some future illumos push changes the MEMCNTL_SHARED assumptions made
- * above, the illumos check below will have to be revisited. This check
- * will work on both pre-and-post illumos#14418 illumos environments.
- */
-#if defined(V8_OS_SOLARIS) && !(defined(__illumos__) && defined(MEMCNTL_SHARED))
+#if defined(V8_OS_SOLARIS)
#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__)
extern "C" int madvise(caddr_t, size_t, int);
#else
diff --git a/deps/v8/src/base/region-allocator.cc b/deps/v8/src/base/region-allocator.cc
index 82642f6ab8c..a7bc479bd08 100644
--- a/deps/v8/src/base/region-allocator.cc
+++ b/deps/v8/src/base/region-allocator.cc
@@ -301,7 +301,8 @@ RegionAllocator::Address RegionAllocator::AllocateRegion(Address hint,
return address;
}
-size_t RegionAllocator::TrimRegion(Address address, size_t new_size) {
+size_t RegionAllocator::TrimRegion(Address address, size_t new_size,
+ AddressRegion* free_region) {
DCHECK(IsAligned(new_size, page_size_));
AllRegionsSet::iterator region_iter = FindRegion(address);
@@ -350,6 +351,7 @@ size_t RegionAllocator::TrimRegion(Address address, size_t new_size) {
}
}
FreeListAddRegion(region);
+ if (free_region) *free_region = *region;
return size;
}
diff --git a/deps/v8/src/base/region-allocator.h b/deps/v8/src/base/region-allocator.h
index 09431254ed0..ead800acc80 100644
--- a/deps/v8/src/base/region-allocator.h
+++ b/deps/v8/src/base/region-allocator.h
@@ -106,13 +106,18 @@ class V8_BASE_EXPORT RegionAllocator final {
// Frees region at given |address|, returns the size of the region.
// There must be a used region starting at given address otherwise nothing
// will be freed and 0 will be returned.
- size_t FreeRegion(Address address) { return TrimRegion(address, 0); }
+ // If |free_region| is given, it receives the free region that the freed
+ // region became part of, after merging with any free neighbours.
+ size_t FreeRegion(Address address, AddressRegion* free_region = nullptr) {
+ return TrimRegion(address, 0, free_region);
+ }
// Decreases size of the previously allocated region at |address|, returns
// freed size. |new_size| must be |page_size|-aligned and
// less than or equal to current region's size. Setting new size to zero
- // frees the region.
- size_t TrimRegion(Address address, size_t new_size);
+ // frees the region. |free_region| is as for FreeRegion().
+ size_t TrimRegion(Address address, size_t new_size,
+ AddressRegion* free_region = nullptr);
// Tries to grow the region at |address| to the size |new_size|. Returns true
// on success.
diff --git a/deps/v8/src/baseline/baseline-compiler.cc b/deps/v8/src/baseline/baseline-compiler.cc
index 304dc849ac9..b09ed33e008 100644
--- a/deps/v8/src/baseline/baseline-compiler.cc
+++ b/deps/v8/src/baseline/baseline-compiler.cc
@@ -836,6 +836,10 @@ void BaselineCompiler::VisitLdaTheHole() {
__ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kTheHoleValue);
}
+void BaselineCompiler::VisitLdaTdzHole() {
+ __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kTdzHoleValue);
+}
+
void BaselineCompiler::VisitLdaTrue() {
__ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kTrueValue);
}
@@ -1207,6 +1211,10 @@ void BaselineCompiler::VisitDefineNamedOwnProperty() {
FeedbackSlotAsTagged(2)); // slot
}
+void BaselineCompiler::VisitDefineNamedOwnPropertyInLiteral() {
+ VisitDefineNamedOwnProperty();
+}
+
void BaselineCompiler::VisitSetKeyedProperty() {
// KeyedStoreIC is currently a base class for multiple keyed property store
// operations and contains mixed logic for set and define operations,
@@ -2820,9 +2828,9 @@ void BaselineCompiler::VisitReturn() {
-profiling_weight);
}
-void BaselineCompiler::VisitThrowReferenceErrorIfHole() {
+void BaselineCompiler::VisitThrowReferenceErrorIfTdzHole() {
Label done;
- __ JumpIfNotRoot(kInterpreterAccumulatorRegister, RootIndex::kTheHoleValue,
+ __ JumpIfNotRoot(kInterpreterAccumulatorRegister, RootIndex::kTdzHoleValue,
&done);
CallRuntime(Runtime::kThrowAccessedUninitializedVariable, Constant<Name>(0));
// Unreachable.
@@ -2830,9 +2838,9 @@ void BaselineCompiler::VisitThrowReferenceErrorIfHole() {
__ Bind(&done);
}
-void BaselineCompiler::VisitThrowSuperNotCalledIfHole() {
+void BaselineCompiler::VisitThrowSuperNotCalledIfTdzHole() {
Label done;
- __ JumpIfNotRoot(kInterpreterAccumulatorRegister, RootIndex::kTheHoleValue,
+ __ JumpIfNotRoot(kInterpreterAccumulatorRegister, RootIndex::kTdzHoleValue,
&done);
CallRuntime(Runtime::kThrowSuperNotCalled);
// Unreachable.
@@ -2840,9 +2848,9 @@ void BaselineCompiler::VisitThrowSuperNotCalledIfHole() {
__ Bind(&done);
}
-void BaselineCompiler::VisitThrowSuperAlreadyCalledIfNotHole() {
+void BaselineCompiler::VisitThrowSuperAlreadyCalledIfNotTdzHole() {
Label done;
- __ JumpIfRoot(kInterpreterAccumulatorRegister, RootIndex::kTheHoleValue,
+ __ JumpIfRoot(kInterpreterAccumulatorRegister, RootIndex::kTdzHoleValue,
&done);
CallRuntime(Runtime::kThrowSuperAlreadyCalledError);
// Unreachable.
diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc
index 7fdedb6e004..b3b37efa1f8 100644
--- a/deps/v8/src/builtins/arm/builtins-arm.cc
+++ b/deps/v8/src/builtins/arm/builtins-arm.cc
@@ -117,7 +117,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// r0: Number of arguments.
Generate_PushArguments(masm, r4, r0, r5, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// r0: number of arguments (untagged)
@@ -186,9 +186,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ b(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(r0, RootIndex::kTheHoleValue);
+ __ LoadRoot(r0, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- r0: receiver
@@ -256,7 +256,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ ldr(r0, MemOperand(sp, 0 * kPointerSize));
- __ JumpIfRoot(r0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1564,7 +1564,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(r2, RootIndex::kTheHoleValue);
+ __ LoadRoot(r2, RootIndex::kTdzHoleValue);
__ Push(cp, r2);
// Push arguments + implicit receiver.
@@ -1625,7 +1625,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ ldr(r0,
MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(r0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc
index 083e3f09db8..17552f4d0dd 100644
--- a/deps/v8/src/builtins/arm64/builtins-arm64.cc
+++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc
@@ -101,7 +101,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
__ Claim(slot_count);
// Preserve the incoming parameters on the stack.
- __ LoadRoot(x4, RootIndex::kTheHoleValue);
+ __ LoadRoot(x4, RootIndex::kTdzHoleValue);
// Compute a pointer to the slot immediately above the location on the
// stack to which arguments will be later copied.
@@ -234,9 +234,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ B(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ Bind(¬_create_implicit_receiver);
- __ LoadRoot(x0, RootIndex::kTheHoleValue);
+ __ LoadRoot(x0, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- x0: receiver
@@ -334,7 +334,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ Bind(&use_receiver);
__ Peek(x0, 0 * kSystemPointerSize);
- __ CompareRoot(x0, RootIndex::kTheHoleValue);
+ __ CompareRoot(x0, RootIndex::kTdzHoleValue);
__ B(eq, &do_throw);
__ Bind(&leave_and_return);
@@ -1245,17 +1245,13 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
FrameScope frame_scope(masm, StackFrame::INTERNAL);
// Save incoming new target or generator
- Register maybe_dispatch_handle = V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL
- ? kJavaScriptCallDispatchHandleRegister
- : padreg;
- // No need to SmiTag as dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- __ AssertSmi(maybe_dispatch_handle);
- __ Push(maybe_dispatch_handle, new_target);
+ __ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, new_target,
+ feedback_cell, feedback_vector);
__ SmiTag(frame_size);
__ PushArgument(frame_size);
__ CallRuntime(Runtime::kStackGuardWithGap);
- __ Pop(new_target, maybe_dispatch_handle);
+ __ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, new_target,
+ feedback_cell, feedback_vector);
}
__ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue);
__ Ret();
@@ -1849,7 +1845,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
}
// Implicit receiver stored in the construct frame.
- __ LoadRoot(x2, RootIndex::kTheHoleValue);
+ __ LoadRoot(x2, RootIndex::kTdzHoleValue);
__ Push(x2, padreg);
// Push arguments + implicit receiver.
@@ -1907,7 +1903,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ Bind(&use_receiver);
__ Ldr(x0,
MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ CompareRoot(x0, RootIndex::kTheHoleValue);
+ __ CompareRoot(x0, RootIndex::kTdzHoleValue);
__ B(eq, &do_throw);
__ Bind(&leave_and_return);
diff --git a/deps/v8/src/builtins/array-join.tq b/deps/v8/src/builtins/array-join.tq
index 324013960e3..e721954d2c7 100644
--- a/deps/v8/src/builtins/array-join.tq
+++ b/deps/v8/src/builtins/array-join.tq
@@ -351,22 +351,14 @@ macro BufferJoin(implicit context: Context)(buffer: Buffer, sep: String):
transitioning macro FastArrayJoin(
implicit context: Context)(kind: constexpr ElementsKind,
- array: FastJSArrayForRead, sep: String, lengthNumber: Number): String
+ array: FastJSArrayForRead, sep: String, length: Smi): String
labels Bailout {
// Check early if the separators might overflow.
- let len: uintptr = Convert<uintptr>(lengthNumber);
- // Fast array length is guaranteed to fit in Smi.
- dcheck(len <= Convert<uintptr>(kFixedArrayMaxLength));
- static_assert(Convert<uintptr>(kFixedArrayMaxLength) < kSmiMaxValue);
- // If separatorLength <= 1, fast arrays cannot overflow the separator counter
- // or exceed kStringMaxLength from separators alone, because their maximum
- // length is bounded by kMaxFastArrayLength (32MB) which is much smaller
- // than kStringMaxLength (268MB/536MB). Thus we only need to perform checks
- // if separatorLength > 1.
- static_assert(
- (Convert<uintptr>(kFixedArrayMaxLength) - 1) <=
- Convert<uintptr>(kStringMaxLength));
-
+ let len: uintptr = Convert<uintptr>(length);
+ dcheck(len <= kStringMaxLengthUintptr);
+ // If separatorLength <= 1, separators alone cannot overflow kStringMaxLength
+ // because length <= kStringMaxLength. Thus we only need to perform checks if
+ // separatorLength > 1.
const separatorLength: intptr = sep.length_intptr;
if (separatorLength > 1 && len > 1) {
const lenInt: int32 = Convert<int32>(Signed(len));
@@ -881,6 +873,11 @@ transitioning builtin ArrayPrototypeJoinImpl(
dcheck(len <= kMaxArrayLength);
try {
+ const smiLen: Smi = Cast<Smi>(len) otherwise Fallback;
+ // FastArrayJoin relies on len <= kStringMaxLength to guarantee that
+ // separators with length <= 1 cannot overflow the maximum string length.
+ if (smiLen > kStringMaxLength) goto Fallback;
+
const castResult = CastFastJSArrayForRead(o) otherwise Fallback;
const fastO = castResult.object;
const elementsKind = castResult.elementsKind;
@@ -888,32 +885,32 @@ transitioning builtin ArrayPrototypeJoinImpl(
if (IsFastSmiElementsKind(elementsKind)) {
if (IsHoleyFastElementsKind(elementsKind)) {
return FastArrayJoin(
- ElementsKind::HOLEY_SMI_ELEMENTS, fastO, separator, len)
+ ElementsKind::HOLEY_SMI_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
} else {
return FastArrayJoin(
- ElementsKind::PACKED_SMI_ELEMENTS, fastO, separator, len)
+ ElementsKind::PACKED_SMI_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
}
} else if (IsDoubleElementsKind(elementsKind)) {
if (IsHoleyFastElementsKind(elementsKind)) {
return FastArrayJoin(
- ElementsKind::HOLEY_DOUBLE_ELEMENTS, fastO, separator, len)
+ ElementsKind::HOLEY_DOUBLE_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
} else {
return FastArrayJoin(
- ElementsKind::PACKED_DOUBLE_ELEMENTS, fastO, separator, len)
+ ElementsKind::PACKED_DOUBLE_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
}
} else if (IsFastElementsKind(elementsKind)) {
if (IsHoleyFastElementsKind(elementsKind)) {
return FastArrayJoin(
- ElementsKind::HOLEY_ELEMENTS, fastO, separator, len)
+ ElementsKind::HOLEY_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
} else {
return FastArrayJoin(
- ElementsKind::PACKED_ELEMENTS, fastO, separator, len)
+ ElementsKind::PACKED_ELEMENTS, fastO, separator, smiLen)
otherwise Fallback;
}
}
diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq
index e3a860d0022..3bbd3108699 100644
--- a/deps/v8/src/builtins/base.tq
+++ b/deps/v8/src/builtins/base.tq
@@ -646,6 +646,7 @@ extern macro SizeStringConstant(): String;
extern macro StringStringConstant(): String;
extern macro SuppressedStringConstant(): String;
extern macro TheHoleConstant(): TheHole;
+extern macro TdzHoleConstant(): TdzHole;
extern macro PromiseHoleConstant(): PromiseHole;
extern macro ToPrimitiveSymbolConstant(): PublicSymbol;
extern macro ToStringStringConstant(): String;
@@ -657,6 +658,7 @@ extern macro ValueOfStringConstant(): String;
extern macro InvalidDispatchHandleConstant(): DispatchHandle;
const TheHole: TheHole = TheHoleConstant();
+const TdzHole: TdzHole = TdzHoleConstant();
const PromiseHole: PromiseHole = PromiseHoleConstant();
const Null: Null = NullConstant();
const Undefined: Undefined = UndefinedConstant();
diff --git a/deps/v8/src/builtins/builtins-api.cc b/deps/v8/src/builtins/builtins-api.cc
index ff7ef690b6e..24c7180fc3b 100644
--- a/deps/v8/src/builtins/builtins-api.cc
+++ b/deps/v8/src/builtins/builtins-api.cc
@@ -65,7 +65,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> HandleApiCallHelper(
Handle<JSReceiver> js_receiver;
if (is_construct) {
- DCHECK(IsTheHole(*receiver));
+ DCHECK(IsTdzHole(*receiver));
if (IsUndefined(fun_data->GetInstanceTemplate())) {
v8::Local<ObjectTemplate> templ =
ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
diff --git a/deps/v8/src/builtins/builtins-arraybuffer.cc b/deps/v8/src/builtins/builtins-arraybuffer.cc
index f3a6e701fa1..1768bee4c08 100644
--- a/deps/v8/src/builtins/builtins-arraybuffer.cc
+++ b/deps/v8/src/builtins/builtins-arraybuffer.cc
@@ -486,7 +486,18 @@ static Tagged<Object> ResizeHelper(BuiltinArguments args, Isolate* isolate,
kMethodName)));
}
- if (is_shared && new_byte_length < array_buffer->GetByteLength()) {
+ auto* extension = array_buffer->extension();
+ // Only resizable ArrayBuffer should get here.
+ SBXCHECK(extension->is_resizable_by_js());
+ SBXCHECK_EQ(extension->is_shared(), SharedFlag(is_shared));
+
+ auto backing_store = extension->backing_store();
+
+ if (is_shared &&
+ new_byte_length < backing_store->byte_length(std::memory_order_seq_cst)) {
+ // `backing_store->byte_length(std::memory_order_seq_cst)` above is
+ // equivalent to the GSAB path of JSArrayBuffer::GetByteLength.
+
// GrowableSharedArrayBuffer is only allowed to grow.
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferResizeLength,
@@ -506,7 +517,6 @@ static Tagged<Object> ResizeHelper(BuiltinArguments args, Isolate* isolate,
// If hostHandled is handled, return undefined.
#ifdef V8_ENABLE_WEBASSEMBLY
- auto backing_store = array_buffer->GetBackingStore();
if (backing_store->is_wasm_memory()) {
size_t old_byte_length =
backing_store->byte_length(std::memory_order_seq_cst);
@@ -549,8 +559,7 @@ static Tagged<Object> ResizeHelper(BuiltinArguments args, Isolate* isolate,
// [RAB] NOTE: Neither creation of the new Data Block nor copying from the
// old Data Block are observable. Implementations reserve the right to
// implement this method as in-place growth or shrinkage.
- if (array_buffer->GetBackingStore()->ResizeInPlace(isolate,
- new_byte_length) !=
+ if (backing_store->ResizeInPlace(isolate, new_byte_length) !=
BackingStore::ResizeOrGrowResult::kSuccess) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kOutOfMemory,
@@ -569,15 +578,14 @@ static Tagged<Object> ResizeHelper(BuiltinArguments args, Isolate* isolate,
}
isolate->heap()->ResizeArrayBufferExtension(
- array_buffer->extension(),
+ extension,
static_cast<int64_t>(new_byte_length) - array_buffer->byte_length());
// [RAB] Set O.[[ArrayBufferByteLength]] to newLength.
array_buffer->set_byte_length(new_byte_length);
} else {
// [GSAB] (Detailed description of the algorithm omitted.)
- auto result =
- array_buffer->GetBackingStore()->GrowInPlace(isolate, new_byte_length);
+ auto result = backing_store->GrowInPlace(isolate, new_byte_length);
if (result == BackingStore::ResizeOrGrowResult::kFailure) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kOutOfMemory,
diff --git a/deps/v8/src/builtins/builtins-date-gen.cc b/deps/v8/src/builtins/builtins-date-gen.cc
index 37125aac607..2c15fa4792a 100644
--- a/deps/v8/src/builtins/builtins-date-gen.cc
+++ b/deps/v8/src/builtins/builtins-date-gen.cc
@@ -5,6 +5,7 @@
#include "src/builtins/builtins-inl.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/codegen/code-stub-assembler-inl.h"
+#include "src/date/date.h"
#include "src/objects/dictionary.h"
namespace v8 {
@@ -72,6 +73,20 @@ void DateBuiltinsAssembler::Generate_DatePrototype_GetField(
std::make_pair(MachineType::Pointer(), isolate_ptr),
std::make_pair(MachineType::AnyTagged(), date_receiver),
std::make_pair(MachineType::AnyTagged(), field_index_smi)));
+ if (field_index == JSDate::kTimezoneOffset) {
+ // The offset comes back in milliseconds because the C function runs under
+ // DisallowGarbageCollection and cannot allocate the HeapNumber that a
+ // fractional-minute offset needs. Divide here instead. The cached path
+ // above would skip this, so the field must be uncached.
+ static_assert(JSDate::kTimezoneOffset >= JSDate::kFirstUncachedField);
+ Label if_nan(this, Label::kDeferred);
+ GotoIfNot(TaggedIsSmi(result), &if_nan);
+ TNode<Smi> offset_ms = CAST(result);
+ Return(ChangeFloat64ToTagged(Float64Div(
+ SmiToFloat64(offset_ms),
+ Float64Constant(static_cast<double>(DateCache::kMsPerMin)))));
+ BIND(&if_nan);
+ }
Return(result);
}
diff --git a/deps/v8/src/builtins/builtins-function.cc b/deps/v8/src/builtins/builtins-function.cc
index b511c42836f..f7ca5412601 100644
--- a/deps/v8/src/builtins/builtins-function.cc
+++ b/deps/v8/src/builtins/builtins-function.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/api/api-inl.h"
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/compiler.h"
#include "src/handles/handle-scope-implementer-inl.h"
#include "src/logging/counters.h"
+#include "src/logging/runtime-call-stats-scope.h"
#include "src/numbers/conversions.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/lookup.h"
@@ -19,6 +21,37 @@ namespace internal {
namespace {
+// Returns an embedder-provided source string, if any, or converts {arg} to a
+// string. Throws if the embedder disallows code generation or ToString fails.
+// TODO: Split this into a dedicated GetCodeForEvalCallback to align
+// with HostGetCodeForEval, which only extracts code. CSP and permission
+// validation belong in HostEnsureCanCompileStrings.
+MaybeDirectHandle<String> GetDynamicFunctionArgumentString(
+ Isolate* isolate, DirectHandle<JSFunction> target, DirectHandle<Object> arg,
+ bool is_code_like,
+ v8::ModifyCodeGenerationFromStringsCallback2 modify_callback,
+ v8::Local<v8::Context> v8_context) {
+ if (IsJSReceiver(*arg) && modify_callback) {
+ v8::Local<v8::Value> v8_arg = Utils::ToLocal(arg);
+ RCS_SCOPE(isolate,
+ RuntimeCallCounterId::kCodeGenerationFromStringsCallbacks);
+ auto result = modify_callback(v8_context, v8_arg, is_code_like);
+ if (isolate->has_exception()) return {};
+ if (!result.codegen_allowed) {
+ Handle<Object> error_message =
+ target->native_context()->ErrorMessageForCodeGenerationFromStrings();
+ THROW_NEW_ERROR(
+ isolate,
+ NewEvalError(MessageTemplate::kCodeGenFromStrings, error_message));
+ }
+ if (!result.modified_source.IsEmpty()) {
+ return Utils::OpenDirectHandle(*result.modified_source.ToLocalChecked());
+ }
+ }
+
+ return Object::ToString(isolate, arg);
+}
+
// ES6 section 19.2.1.1.1 CreateDynamicFunction
MaybeDirectHandle<Object> CreateDynamicFunction(Isolate* isolate,
BuiltinArguments args,
@@ -40,6 +73,38 @@ MaybeDirectHandle<Object> CreateDynamicFunction(Isolate* isolate,
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kNoAccess));
}
+ // Whether the overall constructed function should be treated as
+ // code-like, for use by Compiler::GetFunctionFromString below.
+ auto modify_callback = isolate->modify_code_gen_callback();
+ v8::Local<v8::Context> v8_context =
+ Utils::ToLocal(direct_handle(target->native_context(), isolate));
+
+ // Use an embedder-provided source string when available; otherwise, fall
+ // back to ToString().
+ DirectHandleVector<String> parameter_strings(isolate);
+ if (argc > 1) parameter_strings.reserve(argc - 1);
+
+ // A call with no arguments has nothing trustworthy to base "code-like"
+ // on, so it starts false instead of true.
+ bool is_code_like = argc > 0;
+ DirectHandle<String> body_string = isolate->factory()->empty_string();
+ for (int i = 1; i <= argc; ++i) {
+ DirectHandle<Object> arg = args.at(i);
+ bool argument_is_code_like = Object::IsCodeLike(*arg, isolate);
+ is_code_like &= argument_is_code_like;
+
+ DirectHandle<String> argument_string;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, argument_string,
+ GetDynamicFunctionArgumentString(
+ isolate, target, arg, argument_is_code_like,
+ modify_callback, v8_context));
+ if (i < argc) {
+ parameter_strings.push_back(argument_string);
+ } else {
+ body_string = argument_string;
+ }
+ }
+
// Build the source string.
DirectHandle<String> source;
int parameters_end_pos = kNoSourcePosition;
@@ -48,37 +113,18 @@ MaybeDirectHandle<Object> CreateDynamicFunction(Isolate* isolate,
builder.AppendCharacter('(');
builder.AppendCString(token);
builder.AppendCStringLiteral(" anonymous(");
- if (argc > 1) {
- for (int i = 1; i < argc; ++i) {
- if (i > 1) builder.AppendCharacter(',');
- DirectHandle<String> param;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, param,
- Object::ToString(isolate, args.at(i)));
- param = String::Flatten(isolate, param);
- builder.AppendString(param);
- }
+ for (size_t i = 0; i < parameter_strings.size(); ++i) {
+ if (i > 0) builder.AppendCharacter(',');
+ builder.AppendString(parameter_strings[i]);
}
builder.AppendCharacter('\n');
parameters_end_pos = builder.Length();
builder.AppendCStringLiteral(") {\n");
- if (argc > 0) {
- DirectHandle<String> body;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, body,
- Object::ToString(isolate, args.at(argc)));
- builder.AppendString(body);
- }
+ builder.AppendString(body_string);
builder.AppendCStringLiteral("\n})");
ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish());
}
- bool is_code_like = true;
- for (int i = 0; i < argc; ++i) {
- if (!Object::IsCodeLike(*args.at(i + 1), isolate)) {
- is_code_like = false;
- break;
- }
- }
-
// Compile the string in the constructor and not a helper so that errors to
// come from here.
DirectHandle<JSFunction> function;
diff --git a/deps/v8/src/builtins/builtins-internal-gen.cc b/deps/v8/src/builtins/builtins-internal-gen.cc
index 75deecf7d45..74703bcdb5c 100644
--- a/deps/v8/src/builtins/builtins-internal-gen.cc
+++ b/deps/v8/src/builtins/builtins-internal-gen.cc
@@ -89,8 +89,11 @@ TF_BUILTIN(DebugBreakTrampoline, CodeStubAssembler) {
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
auto dispatch_handle =
UncheckedParameter<JSDispatchHandleT>(Descriptor::kJSDispatchHandle);
+ TNode<Uint16T> expected_parameter_count =
+ LoadParameterCountFromJSDispatchTable(dispatch_handle);
#else
auto dispatch_handle = InvalidDispatchHandleConstant();
+ TNode<Uint16T> expected_parameter_count = Uint16Constant(0);
#endif
auto function = Parameter<JSFunction>(Descriptor::kJSTarget);
@@ -116,7 +119,8 @@ TF_BUILTIN(DebugBreakTrampoline, CodeStubAssembler) {
TailCallJSCode(
TrustedCast<Code>(
code, "used in a call which will be checked via dispatch table"),
- context, function, new_target, arg_count, dispatch_handle);
+ context, function, new_target, arg_count, dispatch_handle,
+ expected_parameter_count);
}
class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
diff --git a/deps/v8/src/builtins/builtins-intl-gen.cc b/deps/v8/src/builtins/builtins-intl-gen.cc
index e095a5528af..d4c7168db24 100644
--- a/deps/v8/src/builtins/builtins-intl-gen.cc
+++ b/deps/v8/src/builtins/builtins-intl-gen.cc
@@ -91,6 +91,10 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) {
TF_BUILTIN(WasmStringToLowerCaseIntl, IntlBuiltinsAssembler) {
auto context = Parameter<Context>(Descriptor::kContext);
auto string = Parameter<String>(Descriptor::kString);
+#ifdef V8_IS_TSAN
+ CallRuntime<Undefined>(Runtime::kTsanAcquireForInitializationFence, context,
+ string);
+#endif
ToLowerCaseImpl(string, TNode<Object>() /*maybe_locales*/, context,
ToLowerCaseKind::kToLowerCase,
[this](TNode<Object> ret) { Return(ret); });
diff --git a/deps/v8/src/builtins/builtins-intl.cc b/deps/v8/src/builtins/builtins-intl.cc
index 4b97358d910..315b5f8c2c7 100644
--- a/deps/v8/src/builtins/builtins-intl.cc
+++ b/deps/v8/src/builtins/builtins-intl.cc
@@ -1241,8 +1241,7 @@ BUILTIN(CollatorInternalCompare) {
Object::ToString(isolate, y));
// 7. Return CompareStrings(collator, X, Y).
- CppGCManaged<icu::Collator>::Ptr icu_collator =
- collator->icu_collator()->ptr();
+ Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
CHECK_NOT_NULL(icu_collator);
int result = Intl::CompareStrings(isolate, *icu_collator, string_x, string_y);
// See StringPrototypeLocaleCompareIntl: the inline fast path relies on
diff --git a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
index 0193b0bd0cd..725786e0b43 100644
--- a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
+++ b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
@@ -69,9 +69,8 @@ class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler {
TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueue(
TNode<Context> native_context) {
CSA_DCHECK(this, IsNativeContext(native_context));
- return LoadCppHeapPointerFromObject(native_context,
- NativeContext::kMicrotaskQueueOffset,
- CppHeapPointerTag::kMicrotaskQueueTag);
+ return LoadCppHeapPointerFromObject(
+ native_context, NativeContext::kMicrotaskQueueOffset, kMicrotaskQueueTag);
}
TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskRingBuffer(
diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc
index 951b56c662f..fa705e82105 100644
--- a/deps/v8/src/builtins/builtins-regexp-gen.cc
+++ b/deps/v8/src/builtins/builtins-regexp-gen.cc
@@ -267,10 +267,10 @@ void RegExpBuiltinsAssembler::ReplayLastMatchInfo(
match_info =
PrepareMatchInfo(context, match_info, SmiTag(register_count), subject);
- // Both sides hold the capture offsets as Smis, so no write barrier is needed.
- CopyRange(match_info, RegExpMatchInfo::OffsetOfElementAt(0), last_match_cache,
- FixedArray::OffsetOfElementAt(0), register_count,
- UNSAFE_SKIP_WRITE_BARRIER);
+ // Both sides hold the capture offsets as Smis.
+ CopyRange<Smi>(match_info, RegExpMatchInfo::OffsetOfElementAt(0),
+ last_match_cache, FixedArray::OffsetOfElementAt(0),
+ register_count);
Goto(&done);
BIND(&done);
@@ -292,10 +292,9 @@ TNode<FixedArray> RegExpBuiltinsAssembler::SnapshotLastMatchInfo(
TNode<FixedArray> snapshot =
CAST(AllocateFixedArray(PACKED_ELEMENTS, register_count));
- // Both sides hold the capture offsets as Smis, so no write barrier is needed.
- CopyRange(snapshot, FixedArray::OffsetOfElementAt(0), match_info,
- RegExpMatchInfo::OffsetOfElementAt(0), register_count,
- UNSAFE_SKIP_WRITE_BARRIER);
+ // Both sides hold the capture offsets as Smis.
+ CopyRange<Smi>(snapshot, FixedArray::OffsetOfElementAt(0), match_info,
+ RegExpMatchInfo::OffsetOfElementAt(0), register_count);
var_result = snapshot;
Goto(&done);
diff --git a/deps/v8/src/builtins/builtins-string-gen.cc b/deps/v8/src/builtins/builtins-string-gen.cc
index 06c2de1f2a7..d282fa8c592 100644
--- a/deps/v8/src/builtins/builtins-string-gen.cc
+++ b/deps/v8/src/builtins/builtins-string-gen.cc
@@ -1014,6 +1014,12 @@ TF_BUILTIN(WasmJSStringEqual, StringBuiltinsAssembler) {
// Callers must handle the case where {lhs} and {rhs} refer to the same
// String object.
CSA_DCHECK(this, TaggedNotEqual(left, right));
+#ifdef V8_IS_TSAN
+ CallRuntime(Runtime::kTsanAcquireForInitializationFence, NoContextConstant(),
+ right);
+ CallRuntime(Runtime::kTsanAcquireForInitializationFence, NoContextConstant(),
+ left);
+#endif
GenerateStringEqual(left, right, length);
}
@@ -1029,6 +1035,12 @@ TF_BUILTIN(WasmStringAdd_NoMapCheck, StringBuiltinsAssembler) {
TF_BUILTIN(WasmStringCompare, StringBuiltinsAssembler) {
auto left = Parameter<String>(Descriptor::kLeft);
auto right = Parameter<String>(Descriptor::kRight);
+#ifdef V8_IS_TSAN
+ CallRuntime(Runtime::kTsanAcquireForInitializationFence, NoContextConstant(),
+ right);
+ CallRuntime(Runtime::kTsanAcquireForInitializationFence, NoContextConstant(),
+ left);
+#endif
GenerateStringRelationalComparison(left, right, StringComparison::kCompare);
}
#endif
diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.cc b/deps/v8/src/builtins/builtins-typed-array-gen.cc
index 6828322b643..9a14e7162b0 100644
--- a/deps/v8/src/builtins/builtins-typed-array-gen.cc
+++ b/deps/v8/src/builtins/builtins-typed-array-gen.cc
@@ -498,7 +498,7 @@ void TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr(
TNode<IntPtrT> ptr_compr_cage_base =
IntPtrSub(full_base, Signed(ChangeUint32ToWord(compressed_base)));
// Add JSTypedArray::ExternalPointerCompensationForOnHeapArray() to offset.
- // See JSTypedArray::AddExternalPointerCompensationForDeserialization().
+ // See JSTypedArray::InitOnHeapDataPtrAfterDeserialization().
DCHECK_EQ(
isolate()->cage_base(),
JSTypedArray::ExternalPointerCompensationForOnHeapArray(isolate()));
diff --git a/deps/v8/src/builtins/cast.tq b/deps/v8/src/builtins/cast.tq
index 0430427fa70..24cd719932b 100644
--- a/deps/v8/src/builtins/cast.tq
+++ b/deps/v8/src/builtins/cast.tq
@@ -247,6 +247,16 @@ Cast<TheHole>(o: HeapObject): TheHole labels CastError {
return Cast<TheHole>(o) otherwise CastError;
}
+Cast<TdzHole>(o: Object): TdzHole labels CastError {
+ if (o == TdzHole) return %RawDownCast<TdzHole>(o);
+ goto CastError;
+}
+
+Cast<TdzHole>(o: HeapObject): TdzHole labels CastError {
+ const o: Object = o;
+ return Cast<TdzHole>(o) otherwise CastError;
+}
+
Cast<True>(o: Object): True labels CastError {
if (o == True) return %RawDownCast<True>(o);
goto CastError;
diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc
index 4af3c368c7c..5ca8c70758c 100644
--- a/deps/v8/src/builtins/ia32/builtins-ia32.cc
+++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc
@@ -111,7 +111,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
Generate_PushArguments(masm, esi, eax, ecx, no_reg,
ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// eax: number of arguments (untagged)
@@ -185,9 +185,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ jmp(&post_instantiation_deopt_entry, Label::kNear);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(eax, RootIndex::kTheHoleValue);
+ __ LoadRoot(eax, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- eax: implicit receiver
@@ -259,7 +259,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ mov(eax, Operand(esp, 0 * kSystemPointerSize));
- __ JumpIfRoot(eax, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(eax, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1579,7 +1579,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
__ Push(esi);
// Implicit receiver stored in the construct frame.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Push arguments + implicit receiver
__ movd(eax, xmm0); // Recover number of arguments.
@@ -1589,7 +1589,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ neg(esi);
__ add(esi, ecx);
GenerateInterpreterPushArgs(masm, esi, ecx);
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Restore context.
__ mov(esi, Operand(ebp, FastConstructFrameConstants::kContextOffset));
@@ -1642,7 +1642,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
// on-stack receiver as the result.
__ bind(&use_receiver);
__ mov(eax, Operand(esp, 0 * kSystemPointerSize));
- __ JumpIfRoot(eax, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(eax, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
__ LeaveFrame(StackFrame::FAST_CONSTRUCT);
diff --git a/deps/v8/src/builtins/js-to-wasm.tq b/deps/v8/src/builtins/js-to-wasm.tq
index 8fc7fe1d54d..8d72eccf7f4 100644
--- a/deps/v8/src/builtins/js-to-wasm.tq
+++ b/deps/v8/src/builtins/js-to-wasm.tq
@@ -64,6 +64,7 @@ const kWasmF64Type:
const kIsFpAlwaysDouble: constexpr bool generates 'wasm::kIsFpAlwaysDouble';
const kIsBigEndian: constexpr bool generates 'wasm::kIsBigEndian';
const kIsBigEndianOnSim: constexpr bool generates 'wasm::kIsBigEndianOnSim';
+const kFP32NeedNanBox: constexpr bool generates 'wasm::kFP32NeedNanBox';
extern enum Promise extends int32 constexpr 'wasm::Promise' {
kPromise,
@@ -692,7 +693,15 @@ macro JSToWasmWrapperHelper(
if constexpr (kIsFpAlwaysDouble || kIsBigEndian || kIsBigEndianOnSim) {
HandleF32Params(context, locationAllocator, toRef, param);
} else {
- *toRef = Convert<intptr>(Bitcast<uint32>(WasmTaggedToFloat32(param)));
+ const raw =
+ Convert<intptr>(Bitcast<uint32>(WasmTaggedToFloat32(param)));
+ if constexpr (kFP32NeedNanBox) {
+ // The assembly wrapper reloads f32 parameters with a 64-bit FP load
+ // (fld), so the slot must already contain a NaN-boxed f32.
+ *toRef = raw | (Convert<intptr>(0xffffffff) << 32);
+ } else {
+ *toRef = raw;
+ }
// TODO(nicohartmann,385155404): When passing a NaN to Wasm, every
// single bit can be observable when the float64 is reinterpret casted
// to an integral type. Hence, differences in NaN bit patterns are
diff --git a/deps/v8/src/builtins/js-trampoline-assembler.cc b/deps/v8/src/builtins/js-trampoline-assembler.cc
index 1f5c17a22c5..1b1fbc5e9ac 100644
--- a/deps/v8/src/builtins/js-trampoline-assembler.cc
+++ b/deps/v8/src/builtins/js-trampoline-assembler.cc
@@ -16,7 +16,8 @@ namespace internal {
#include "src/codegen/define-code-stub-assembler-macros.inc"
-void JSTrampolineAssembler::TailCallJSFunction(TNode<JSFunction> function) {
+void JSTrampolineAssembler::TailCallJSFunction(
+ TNode<JSFunction> function, TNode<Uint16T> expected_parameter_count) {
auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
auto context = Parameter<Context>(Descriptor::kContext);
auto new_target = Parameter<Object>(Descriptor::kNewTarget);
@@ -33,12 +34,22 @@ void JSTrampolineAssembler::TailCallJSFunction(TNode<JSFunction> function) {
function, offsetof(JSFunction, dispatch_handle_))));
// TailCallJSCode will load the code from the dispatch table.
- TailCallJSCode(context, function, new_target, argc, dispatch_handle);
+ TailCallJSCode(context, function, new_target, argc, dispatch_handle,
+ expected_parameter_count);
}
-
void JSTrampolineAssembler::CompileLazy(TNode<JSFunction> function,
TNode<Context> context) {
+#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
+ auto dispatch_handle =
+ UncheckedParameter<JSDispatchHandleT>(Descriptor::kDispatchHandle);
+ TNode<Uint16T> expected_parameter_count =
+ LoadParameterCountFromJSDispatchTable(dispatch_handle);
+#else
+ CHECK(!V8_ENABLE_SANDBOX_BOOL);
+ TNode<Uint16T> expected_parameter_count = Uint16Constant(0);
+#endif
+
// First lookup code, maybe we don't need to compile!
Label compile_function(this, Label::kDeferred);
@@ -80,11 +91,11 @@ void JSTrampolineAssembler::CompileLazy(TNode<JSFunction> function,
// necessary as the dispatch table entry may still contain the CompileLazy
// builtin at this point (we can only update dispatch table code from C++).
CallRuntime(Runtime::kInstallSFICode, context, function);
- TailCallJSFunction(function);
+ TailCallJSFunction(function, expected_parameter_count);
BIND(&compile_function);
CallRuntime(Runtime::kCompileLazy, context, function);
- TailCallJSFunction(function);
+ TailCallJSFunction(function, expected_parameter_count);
}
TF_BUILTIN(CompileLazy, JSTrampolineAssembler) {
@@ -105,10 +116,13 @@ void JSTrampolineAssembler::TieringBuiltinImpl(const Function& Impl) {
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
auto dispatch_handle =
UncheckedParameter<JSDispatchHandleT>(Descriptor::kDispatchHandle);
+ TNode<Uint16T> expected_parameter_count =
+ LoadParameterCountFromJSDispatchTable(dispatch_handle);
#else
CHECK(!V8_ENABLE_SANDBOX_BOOL);
auto dispatch_handle = LoadObjectField<JSDispatchHandleT>(
function, offsetof(JSFunction, dispatch_handle_));
+ TNode<Uint16T> expected_parameter_count = Uint16Constant(0);
#endif
// Apply the actual tiering. This function must uninstall the tiering builtin.
@@ -123,7 +137,8 @@ void JSTrampolineAssembler::TieringBuiltinImpl(const Function& Impl) {
// TailCallJSCode will load the code from the dispatch table to guarantee
// that the signature of the code matches with the number of arguments
// passed when calling into this trampoline.
- TailCallJSCode(context, function, new_target, argc, dispatch_handle);
+ TailCallJSCode(context, function, new_target, argc, dispatch_handle,
+ expected_parameter_count);
}
TF_BUILTIN(FunctionLogNextExecution, JSTrampolineAssembler) {
diff --git a/deps/v8/src/builtins/js-trampoline-assembler.h b/deps/v8/src/builtins/js-trampoline-assembler.h
index 21762a95295..f0b342bb986 100644
--- a/deps/v8/src/builtins/js-trampoline-assembler.h
+++ b/deps/v8/src/builtins/js-trampoline-assembler.h
@@ -18,7 +18,8 @@ class JSTrampolineAssembler : public CodeStubAssembler {
explicit JSTrampolineAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
- void TailCallJSFunction(TNode<JSFunction> function);
+ void TailCallJSFunction(TNode<JSFunction> function,
+ TNode<Uint16T> expected_parameter_count);
template <typename Function>
void TieringBuiltinImpl(const Function& Impl);
diff --git a/deps/v8/src/builtins/loong64/builtins-loong64.cc b/deps/v8/src/builtins/loong64/builtins-loong64.cc
index 1257a6ee3b0..e3272c0fe56 100644
--- a/deps/v8/src/builtins/loong64/builtins-loong64.cc
+++ b/deps/v8/src/builtins/loong64/builtins-loong64.cc
@@ -108,7 +108,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// a0: Number of arguments.
Generate_PushArguments(masm, t2, a0, t3, t0, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// a0: number of arguments (untagged)
@@ -179,9 +179,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ Branch(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(a0, RootIndex::kTheHoleValue);
+ __ LoadRoot(a0, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- a0: receiver
@@ -262,7 +262,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ Ld_d(a0, MemOperand(sp, 0 * kSystemPointerSize));
- __ JumpIfRoot(a0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(a0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1065,16 +1065,15 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
// Save incoming new target or generator
__ Push(kJavaScriptCallNewTargetRegister);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- // No need to SmiTag as dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- __ AssertSmi(kJavaScriptCallDispatchHandleRegister);
- __ Push(kJavaScriptCallDispatchHandleRegister);
+ __ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, feedback_cell,
+ feedback_vector);
#endif
__ SmiTag(frame_size);
__ Push(frame_size);
__ CallRuntime(Runtime::kStackGuardWithGap);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- __ Pop(kJavaScriptCallDispatchHandleRegister);
+ __ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, feedback_cell,
+ feedback_vector);
#endif
__ Pop(kJavaScriptCallNewTargetRegister);
}
@@ -1614,7 +1613,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(a2, RootIndex::kTheHoleValue);
+ __ LoadRoot(a2, RootIndex::kTdzHoleValue);
__ Push(cp, a2);
// Push arguments + implicit receiver.
@@ -1671,7 +1670,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ Ld_d(a0,
MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(a0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(a0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc
index e811c841236..ba302ca33ee 100644
--- a/deps/v8/src/builtins/mips64/builtins-mips64.cc
+++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc
@@ -106,7 +106,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// a0: Number of arguments.
Generate_PushArguments(masm, t2, a0, t3, t0, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// a0: number of arguments (untagged)
@@ -176,9 +176,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ Branch(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(v0, RootIndex::kTheHoleValue);
+ __ LoadRoot(v0, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- v0: receiver
@@ -258,7 +258,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ Ld(v0, MemOperand(sp, 0 * kSystemPointerSize));
- __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(v0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1552,7 +1552,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(a2, RootIndex::kTheHoleValue);
+ __ LoadRoot(a2, RootIndex::kTdzHoleValue);
__ Push(cp, a2);
// Push arguments + implicit receiver.
@@ -1608,7 +1608,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ Ld(v0,
MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(v0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/ppc/builtins-ppc.cc b/deps/v8/src/builtins/ppc/builtins-ppc.cc
index 60be0d9367c..801176b74a4 100644
--- a/deps/v8/src/builtins/ppc/builtins-ppc.cc
+++ b/deps/v8/src/builtins/ppc/builtins-ppc.cc
@@ -359,7 +359,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
Generate_PushArguments(masm, r7, r3, r8, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// r3: number of arguments (untagged)
@@ -527,9 +527,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ b(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(r3, RootIndex::kTheHoleValue);
+ __ LoadRoot(r3, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- r3: receiver
@@ -607,7 +607,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ LoadU64(r3, MemOperand(sp));
- __ JumpIfRoot(r3, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r3, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1841,7 +1841,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(r5, RootIndex::kTheHoleValue);
+ __ LoadRoot(r5, RootIndex::kTdzHoleValue);
__ Push(cp, r5);
// Push arguments + implicit receiver.
@@ -1908,7 +1908,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ LoadU64(
r3, MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(r3, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r3, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/riscv/builtins-riscv.cc b/deps/v8/src/builtins/riscv/builtins-riscv.cc
index e35e8861d0d..a663f76a2f2 100644
--- a/deps/v8/src/builtins/riscv/builtins-riscv.cc
+++ b/deps/v8/src/builtins/riscv/builtins-riscv.cc
@@ -223,7 +223,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
ArgumentsElementType::kRaw);
}
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// a0: number of arguments (untagged)
@@ -292,9 +292,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ BranchShort(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(a0, RootIndex::kTheHoleValue);
+ __ LoadRoot(a0, RootIndex::kTdzHoleValue);
}
// ----------- S t a t e -------------
// -- a0: receiver
@@ -382,7 +382,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ LoadWord(a0, MemOperand(sp, 0 * kSystemPointerSize));
- __ JumpIfRoot(a0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(a0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -517,8 +517,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
Register dispatch_handle = kJavaScriptCallDispatchHandleRegister;
Register code = kJavaScriptCallCodeStartRegister; // a2
Register scratch = t2;
- __ Lw(dispatch_handle,
- FieldMemOperand(a5, offsetof(JSFunction, dispatch_handle_)));
+ __ Lwu(dispatch_handle,
+ FieldMemOperand(a5, offsetof(JSFunction, dispatch_handle_)));
__ LoadEntrypointAndParameterCountFromJSDispatchTable(
code, argc, dispatch_handle, scratch);
// In case the formal parameter count is kDontAdaptArgumentsSentinel the
@@ -1225,17 +1225,16 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
__ Push(kJavaScriptCallNewTargetRegister);
#if defined(V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE) && \
defined(V8_TARGET_ARCH_RISCV64)
- // No need to SmiTag as dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- __ AssertSmi(kJavaScriptCallDispatchHandleRegister);
- __ Push(kJavaScriptCallDispatchHandleRegister);
+ __ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, feedback_cell,
+ feedback_vector);
#endif
__ SmiTag(frame_size);
__ Push(frame_size);
__ CallRuntime(Runtime::kStackGuardWithGap);
#if defined(V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE) && \
defined(V8_TARGET_ARCH_RISCV64)
- __ Pop(kJavaScriptCallDispatchHandleRegister);
+ __ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, feedback_cell,
+ feedback_vector);
#endif
__ Pop(kJavaScriptCallNewTargetRegister);
}
@@ -1786,7 +1785,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(a2, RootIndex::kTheHoleValue);
+ __ LoadRoot(a2, RootIndex::kTdzHoleValue);
__ Push(cp, a2);
// Push arguments + implicit receiver.
@@ -1842,7 +1841,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ LoadWord(
a0, MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(a0, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(a0, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/s390/builtins-s390.cc b/deps/v8/src/builtins/s390/builtins-s390.cc
index 78f88bc4726..8d7e01cb739 100644
--- a/deps/v8/src/builtins/s390/builtins-s390.cc
+++ b/deps/v8/src/builtins/s390/builtins-s390.cc
@@ -434,7 +434,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
Generate_PushArguments(masm, r6, r2, r1, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// r2: number of arguments
@@ -506,9 +506,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ b(&post_instantiation_deopt_entry);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(r2, RootIndex::kTheHoleValue);
+ __ LoadRoot(r2, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- r2: receiver
@@ -582,7 +582,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ LoadU64(r2, MemOperand(sp));
- __ JumpIfRoot(r2, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r2, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Restore arguments count from the frame.
@@ -1887,7 +1887,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
// Implicit receiver stored in the construct frame.
- __ LoadRoot(r4, RootIndex::kTheHoleValue);
+ __ LoadRoot(r4, RootIndex::kTdzHoleValue);
__ Push(cp, r4);
// Push arguments + implicit receiver.
@@ -1949,7 +1949,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ LoadU64(
r2, MemOperand(fp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(r2, RootIndex::kTheHoleValue, &do_throw);
+ __ JumpIfRoot(r2, RootIndex::kTdzHoleValue, &do_throw);
__ bind(&leave_and_return);
// Leave construct frame.
diff --git a/deps/v8/src/builtins/wasm.tq b/deps/v8/src/builtins/wasm.tq
index 9f06bebc51a..2f85cf06de0 100644
--- a/deps/v8/src/builtins/wasm.tq
+++ b/deps/v8/src/builtins/wasm.tq
@@ -44,8 +44,12 @@ extern runtime WasmI32AtomicWait(
Context, WasmTrustedInstanceData, Smi, Number, Number, BigInt): Smi;
extern runtime WasmI64AtomicWait(
Context, WasmTrustedInstanceData, Smi, Number, BigInt, BigInt): Smi;
-extern runtime WasmManagedObjectWait(
+extern runtime WasmManagedObjectWait32(
Context, HeapObject, Smi, Number, HeapObject, BigInt): Smi;
+extern runtime WasmManagedObjectWait64(
+ Context, HeapObject, Smi, BigInt, HeapObject, BigInt): Smi;
+extern runtime WasmManagedObjectWaitRef(
+ Context, HeapObject, Smi, Object, HeapObject, BigInt): Smi;
extern runtime WasmWaitqueueNew(Context): HeapObject;
extern runtime WasmArrayCopy(Context, WasmArray, Smi, WasmArray, Smi, Smi):
JSAny;
@@ -96,6 +100,7 @@ extern runtime AllocateInSharedHeap(Context, Smi, Smi): HeapObject;
extern runtime WasmConfigureAllPrototypesOpt(
Context, Object, JSAny, WasmTrustedInstanceData): Object;
extern runtime WasmTypeAssertionFailed(NoContext): never;
+extern runtime TsanAcquireForInitializationFence(NoContext, Object): Undefined;
}
extern operator '.wasm_exported_function_data' macro
@@ -704,15 +709,33 @@ builtin WasmI64AtomicWait(
return Unsigned(SmiToInt32(result));
}
-builtin WasmManagedObjectWait(
+builtin WasmManagedObjectWait32(
object: HeapObject, fieldOffset: int32, expectedValue: int32,
waitqueue: HeapObject, timeout: BigInt): uint32 {
- const result: Smi = runtime::WasmManagedObjectWait(
+ const result: Smi = runtime::WasmManagedObjectWait32(
LoadContextFromFrame(), object, SmiFromInt32(fieldOffset),
ChangeInt32ToTagged(expectedValue), waitqueue, timeout);
return Unsigned(SmiToInt32(result));
}
+builtin WasmManagedObjectWait64(
+ object: HeapObject, fieldOffset: int32, expectedValue: BigInt,
+ waitqueue: HeapObject, timeout: BigInt): uint32 {
+ const result: Smi = runtime::WasmManagedObjectWait64(
+ LoadContextFromFrame(), object, SmiFromInt32(fieldOffset), expectedValue,
+ waitqueue, timeout);
+ return Unsigned(SmiToInt32(result));
+}
+
+builtin WasmManagedObjectWaitRef(
+ object: HeapObject, fieldOffset: int32, expectedValue: Object,
+ waitqueue: HeapObject, timeout: BigInt): uint32 {
+ const result: Smi = runtime::WasmManagedObjectWaitRef(
+ LoadContextFromFrame(), object, SmiFromInt32(fieldOffset), expectedValue,
+ waitqueue, timeout);
+ return Unsigned(SmiToInt32(result));
+}
+
builtin WasmWaitqueueNew(): HeapObject {
tail runtime::WasmWaitqueueNew(LoadContextFromFrame());
}
@@ -1058,6 +1081,9 @@ macro StringFromTwoByteSlice(length: uint32, slice: ConstSlice<char16>):
builtin WasmStringNewWtf16Array(
array: WasmArray, start: uint32, end: uint32, config: Smi): String {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, array);
+ }
try {
if (array.length < end) goto OffsetOutOfRange;
if (end < start) goto OffsetOutOfRange;
@@ -1130,6 +1156,9 @@ builtin WasmStringFromDataSegment(
// Contract: input is any string, output is a string that the TF operator
// "StringPrepareForGetCodeunit" can handle.
builtin WasmStringAsWtf16(str: String): String {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, str);
+ }
const cons = Cast<ConsString>(str) otherwise return str;
return Flatten(cons);
}
@@ -1181,6 +1210,7 @@ builtin WasmStringEncodeWtf16(string: String, offset: uintptr, memory: uint32):
}
builtin WasmStringEncodeWtf16Array(
string: String, array: WasmArray, start: uint32): uint32 {
+ // TODO(manoskouk): Can we disable TSAN for this builtin?
try {
if (start > array.length) goto OffsetOutOfRange;
if (array.length - start < Unsigned(string.length)) goto OffsetOutOfRange;
@@ -1260,6 +1290,10 @@ builtin WasmStringAdd_NoMapCheck_Shared(a: String, b: String): String {
extern builtin StringEqual(NoContext, String, String, intptr): Boolean;
builtin WasmStringEqual(a: String, b: String): int32 {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, a);
+ runtime::TsanAcquireForInitializationFence(kNoContext, b);
+ }
if (TaggedEqual(a, b)) return 1;
if (a.length != b.length) return 0;
if (StringEqual(kNoContext, a, b, a.length_intptr) == True) {
@@ -1431,6 +1465,9 @@ transitioning builtin WasmStringViewWtf16Slice(
}
builtin WasmStringSliceShared(string: String, start: uint32, end: uint32):
String {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, string);
+ }
const length = Unsigned(string.length);
if (start >= length) return kEmptyString;
if (end <= start) return kEmptyString;
@@ -1476,6 +1513,9 @@ macro CombineSurrogatePair(lead: char16, trail: char16): int32 {
}
builtin WasmStringCodePointAt(string: String, offset: uint32): uint32 {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, string);
+ }
try {
if (Unsigned(string.length) <= offset) goto OffsetOutOfRange;
const lead: char16 = StringCharCodeAt(string, Convert<uintptr>(offset));
@@ -1654,6 +1694,10 @@ builtin WasmFastApiCallTypeCheckAndUpdateIC(
}
builtin WasmStringIndexOf(s: String, searchString: String, start: Smi): Smi {
+ @if(V8_IS_TSAN) {
+ runtime::TsanAcquireForInitializationFence(kNoContext, s);
+ runtime::TsanAcquireForInitializationFence(kNoContext, searchString);
+ }
return AbstractStringIndexOf(s, searchString, SmiMax(start, 0));
}
diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc
index c5cb7ddda09..a5a151bfac7 100644
--- a/deps/v8/src/builtins/x64/builtins-x64.cc
+++ b/deps/v8/src/builtins/x64/builtins-x64.cc
@@ -112,7 +112,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
// rax: Number of arguments.
Generate_PushArguments(masm, rbx, rax, rcx, ArgumentsElementType::kRaw);
// The receiver for the builtin/api call.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Call the function.
// rax: number of arguments (untagged)
@@ -211,9 +211,9 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ CallBuiltin(Builtin::kFastNewObject);
__ jmp(&post_instantiation_deopt_entry, Label::kNear);
- // Else: use TheHoleValue as receiver for constructor call
+ // Else: use TdzHoleValue as receiver for constructor call
__ bind(¬_create_implicit_receiver);
- __ LoadRoot(rax, RootIndex::kTheHoleValue);
+ __ LoadRoot(rax, RootIndex::kTdzHoleValue);
// ----------- S t a t e -------------
// -- rax implicit receiver
@@ -282,7 +282,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// on-stack receiver as the result.
__ bind(&use_receiver);
__ movq(rax, Operand(rsp, 0 * kSystemPointerSize));
- __ JumpIfRoot(rax, RootIndex::kTheHoleValue, &do_throw, Label::kNear);
+ __ JumpIfRoot(rax, RootIndex::kTdzHoleValue, &do_throw, Label::kNear);
__ bind(&leave_and_return);
// Restore the arguments count.
@@ -1599,14 +1599,14 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ EnterFrame(StackFrame::FAST_CONSTRUCT);
__ Push(rsi);
// Implicit receiver stored in the construct frame.
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Push arguments + implicit receiver.
Register argc_without_receiver = r11;
__ leaq(argc_without_receiver, Operand(rax, -kJSArgcReceiverSlots));
GenerateInterpreterPushArgs(masm, argc_without_receiver, rcx, r12);
// Implicit receiver as part of the arguments (patched later if needed).
- __ PushRoot(RootIndex::kTheHoleValue);
+ __ PushRoot(RootIndex::kTdzHoleValue);
// Check if it is a builtin call.
Label builtin_call;
@@ -1664,7 +1664,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
__ bind(&use_receiver);
__ movq(rax,
Operand(rbp, FastConstructFrameConstants::kImplicitReceiverOffset));
- __ JumpIfRoot(rax, RootIndex::kTheHoleValue, &do_throw, Label::kNear);
+ __ JumpIfRoot(rax, RootIndex::kTdzHoleValue, &do_throw, Label::kNear);
__ bind(&leave_and_return);
__ LeaveFrame(StackFrame::FAST_CONSTRUCT);
@@ -1962,16 +1962,13 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
// Save incoming new target or generator
__ Push(new_target);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- // No need to SmiTag as dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- __ AssertSmi(kJavaScriptCallDispatchHandleRegister);
- __ Push(kJavaScriptCallDispatchHandleRegister);
+ __ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, rcx);
#endif
__ SmiTag(frame_size);
__ Push(frame_size);
__ CallRuntime(Runtime::kStackGuardWithGap, 1);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- __ Pop(kJavaScriptCallDispatchHandleRegister);
+ __ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, rcx);
#endif
__ Pop(new_target);
}
diff --git a/deps/v8/src/codegen/arm/macro-assembler-arm.h b/deps/v8/src/codegen/arm/macro-assembler-arm.h
index 45e46f917ee..ab3048481cf 100644
--- a/deps/v8/src/codegen/arm/macro-assembler-arm.h
+++ b/deps/v8/src/codegen/arm/macro-assembler-arm.h
@@ -584,6 +584,12 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadTaggedRoot(Register destination, RootIndex index) {
LoadRoot(destination, index);
}
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+ }
void LoadRoot(Register destination, RootIndex index) final {
LoadRoot(destination, index, al);
}
diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
index a797c09ef53..a79bd6d3186 100644
--- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
+++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
@@ -1499,24 +1499,20 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
FrameScope scope(this, StackFrame::INTERNAL);
// Push a copy of the target function, the new target, the actual
// argument count, and the dispatch handle.
- Register maybe_dispatch_handle = V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL
- ? kJavaScriptCallDispatchHandleRegister
- : padreg;
SmiTag(kJavaScriptCallArgCountRegister);
- // No need to SmiTag the dispatch handle as it always looks like a Smi.
- static_assert(kJSDispatchHandleShift > 0);
- AssertSmi(maybe_dispatch_handle);
- Push(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
- kJavaScriptCallArgCountRegister, maybe_dispatch_handle);
+ Push(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister);
+ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister,
+ kJavaScriptCallArgCountRegister, x5, x6);
// Push another copy as a parameter to the runtime call.
PushArgument(kJavaScriptCallTargetRegister);
CallRuntime(function_id, 1);
- // Restore target function, new target, actual argument count, and dispatch
+ // Restore target function, new target, actual argument count and dispatch
// handle.
- Pop(maybe_dispatch_handle, kJavaScriptCallArgCountRegister,
- kJavaScriptCallNewTargetRegister, kJavaScriptCallTargetRegister);
+ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister,
+ kJavaScriptCallArgCountRegister, x5, x6);
+ Pop(kJavaScriptCallNewTargetRegister, kJavaScriptCallTargetRegister);
SmiUntag(kJavaScriptCallArgCountRegister);
}
@@ -1911,6 +1907,15 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
LoadRoot(destination, index);
}
+void MacroAssembler::StoreTaggedRoot(const MemOperand& destination,
+ RootIndex index) {
+ ASM_CODE_COMMENT(this);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.AcquireX();
+ LoadTaggedRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+}
+
void MacroAssembler::LoadRoot(Register destination, RootIndex index) {
ASM_CODE_COMMENT(this);
if (V8_STATIC_ROOTS_BOOL && RootsTable::IsReadOnly(index) &&
@@ -4091,6 +4096,40 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
MemOperand(scratch, JSDispatchEntry::kCodeObjectOffset));
}
+void MacroAssembler::PushDispatchHandle(Register dispatch_handle,
+ Register other, Register scratch1,
+ Register scratch2) {
+ Register maybe_dispatch_handle =
+ V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL ? dispatch_handle : padreg;
+#ifdef V8_ENABLE_SANDBOX
+ DCHECK(!AreAliased(dispatch_handle, other, scratch1, scratch2));
+ AssertZeroExtended(dispatch_handle);
+ LoadParameterCountFromJSDispatchTable(scratch1, dispatch_handle, scratch2);
+ Bfi(dispatch_handle, scratch1, 32, 32);
+#endif
+ Push(maybe_dispatch_handle, other);
+ // No need to SmiTag as dispatch handles always look like Smis.
+ static_assert(kJSDispatchHandleShift > 0);
+ AssertSmi(maybe_dispatch_handle);
+}
+
+void MacroAssembler::PopDispatchHandle(Register dispatch_handle, Register other,
+ Register scratch1, Register scratch2) {
+ Register maybe_dispatch_handle =
+ V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL ? dispatch_handle : padreg;
+ Pop(other, maybe_dispatch_handle);
+#ifdef V8_ENABLE_SANDBOX
+ DCHECK(!AreAliased(dispatch_handle, other, scratch1, scratch2));
+ UseScratchRegisterScope temps(this);
+ Lsr(scratch1, dispatch_handle, 32);
+ Uxtw(dispatch_handle, dispatch_handle);
+ LoadParameterCountFromJSDispatchTable(scratch2, dispatch_handle,
+ temps.AcquireX());
+ Cmp(scratch1, scratch2);
+ SbxCheck(eq, AbortReason::kJSSignatureMismatch);
+#endif
+}
+
void MacroAssembler::LoadProtectedPointerField(Register destination,
MemOperand field_operand) {
DCHECK(root_array_available());
diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
index 9467b9b2cf2..ec3b6eb71c0 100644
--- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
+++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
@@ -1514,6 +1514,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Load an object from the root table.
void LoadRoot(Register destination, RootIndex index) final;
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index);
void PushRoot(RootIndex index);
inline void Ret(const Register& xn = lr);
@@ -1729,6 +1730,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadEntrypointAndParameterCountFromJSDispatchTable(
Register entrypoint, Register parameter_count, Register dispatch_handle,
Register scratch);
+ void PushDispatchHandle(Register dispatch_handle, Register other,
+ Register scratch1, Register scratch2);
+ void PopDispatchHandle(Register dispatch_handle, Register other,
+ Register scratch1, Register scratch2);
// Load a protected pointer field.
void LoadProtectedPointerField(Register destination,
diff --git a/deps/v8/src/codegen/code-stub-assembler.cc b/deps/v8/src/codegen/code-stub-assembler.cc
index 19d51a7be0b..200a57e7574 100644
--- a/deps/v8/src/codegen/code-stub-assembler.cc
+++ b/deps/v8/src/codegen/code-stub-assembler.cc
@@ -2217,16 +2217,7 @@ TNode<Code> CodeStubAssembler::LoadCodeObjectFromJSDispatchTable(
TNode<UintPtrT> shifted_value;
if (JSDispatchEntry::kObjectPointerOffset == 0) {
shifted_value =
-#if defined(__illumos__) && defined(V8_HOST_ARCH_64_BIT)
- // Pointers in illumos span both the low 2^47 range and the high 2^47 range
- // as well. Checking the high bit being set in illumos means all higher bits
- // need to be set to 1 after shifting right.
- // Use WordSar() so any high-bit check wouldn't be necessary.
- UncheckedCast<UintPtrT>(WordSar(UncheckedCast<IntPtrT>(value),
- IntPtrConstant(JSDispatchEntry::kObjectPointerShift)));
-#else
WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift));
-#endif /* __illumos__ and 64-bit */
} else {
shifted_value = UintPtrAdd(
WordShr(value, UintPtrConstant(JSDispatchEntry::kObjectPointerShift)),
@@ -2249,19 +2240,24 @@ TNode<Uint16T> CodeStubAssembler::LoadParameterCountFromJSDispatchTable(
return Load<Uint16T>(table, offset);
}
-
void CodeStubAssembler::TailCallJSCode(
TNode<Code> code, TNode<Context> context, TNode<JSFunction> function,
TNode<Object> new_target, TNode<Int32T> arg_count,
- TNode<JSDispatchHandleT> dispatch_handle) {
+ TNode<JSDispatchHandleT> dispatch_handle,
+ TNode<Uint16T> expected_parameter_count) {
#ifdef V8_ENABLE_SANDBOX
- // Check that the code has a matching parameter count. This ensures that
- // the target code will correctly tear down parameters when leaving.
+ // Check that the code and dispatch table entry still have the expected
+ // parameter count. This ensures that the target code matches the native
+ // argument frame and will correctly tear down parameters when leaving.
static_assert(V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL);
CSA_SBXCHECK(
this,
- Word32Equal(LoadCodeParameterCount(code),
+ Word32Equal(expected_parameter_count,
LoadParameterCountFromJSDispatchTable(dispatch_handle)));
+ CSA_SBXCHECK(this, Word32Equal(LoadCodeParameterCount(code),
+ expected_parameter_count));
+#else
+ USE(expected_parameter_count);
#endif // V8_ENABLE_SANDBOX
CodeAssembler::TailCallJSCode(code, context, function, new_target, arg_count,
@@ -2271,7 +2267,21 @@ void CodeStubAssembler::TailCallJSCode(
void CodeStubAssembler::TailCallJSCode(
TNode<Context> context, TNode<JSFunction> function,
TNode<Object> new_target, TNode<Int32T> arg_count,
- TNode<JSDispatchHandleT> dispatch_handle) {
+ TNode<JSDispatchHandleT> dispatch_handle,
+ TNode<Uint16T> expected_parameter_count) {
+#ifdef V8_ENABLE_SANDBOX
+ // In regular execution, the dispatch entry is kept alive via the target
+ // JSFunction on the stack. However, with in-sandbox memory corruption, a
+ // dispatch handle may not be kept alive and its entry could be swept and
+ // reallocated with a different parameter count during a GC in the runtime.
+ static_assert(V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE_BOOL);
+ CSA_SBXCHECK(
+ this,
+ Word32Equal(expected_parameter_count,
+ LoadParameterCountFromJSDispatchTable(dispatch_handle)));
+#else
+ USE(expected_parameter_count);
+#endif // V8_ENABLE_SANDBOX
TNode<Code> code = LoadCodeObjectFromJSDispatchTable(dispatch_handle);
CodeAssembler::TailCallJSCode(code, context, function, new_target, arg_count,
@@ -6692,10 +6702,14 @@ void CodeStubAssembler::CopyElements(ElementsKind kind,
}
}
+template <class T>
void CodeStubAssembler::CopyRange(TNode<HeapObject> dst_object, int dst_offset,
TNode<HeapObject> src_object, int src_offset,
TNode<IntPtrT> length_in_tagged,
WriteBarrierMode mode) {
+ DCHECK(mode == UPDATE_WRITE_BARRIER || mode == SKIP_WRITE_BARRIER);
+ const WriteBarrierMode barrier_mode =
+ std::is_same_v<T, Smi> ? SKIP_WRITE_BARRIER : mode;
// TODO(jgruber): This could be a lot more involved (e.g. better code when
// write barriers can be skipped). Extend as needed.
BuildFastLoop<IntPtrT>(
@@ -6703,15 +6717,11 @@ void CodeStubAssembler::CopyRange(TNode<HeapObject> dst_object, int dst_offset,
[=, this](TNode<IntPtrT> index) {
TNode<IntPtrT> current_src_offset =
IntPtrAdd(TimesTaggedSize(index), IntPtrConstant(src_offset));
- TNode<Object> value = LoadObjectField(src_object, current_src_offset);
+ TNode<T> value =
+ LoadCopyRangeElement<T>(src_object, current_src_offset);
TNode<IntPtrT> current_dst_offset =
IntPtrAdd(TimesTaggedSize(index), IntPtrConstant(dst_offset));
- if (mode == UNSAFE_SKIP_WRITE_BARRIER) {
- UnsafeStoreNoWriteBarrier(
- MachineRepresentation::kTagged, dst_object,
- IntPtrSub(current_dst_offset, IntPtrConstant(kHeapObjectTag)),
- value);
- } else if (mode == SKIP_WRITE_BARRIER) {
+ if (barrier_mode == SKIP_WRITE_BARRIER) {
StoreObjectFieldNoWriteBarrier(dst_object, current_dst_offset, value);
} else {
StoreObjectField(dst_object, current_dst_offset, value);
@@ -6720,6 +6730,13 @@ void CodeStubAssembler::CopyRange(TNode<HeapObject> dst_object, int dst_offset,
1, kLoopUnrolling, IndexAdvanceMode::kPost);
}
+template V8_EXPORT_PRIVATE void CodeStubAssembler::CopyRange<Object>(
+ TNode<HeapObject>, int, TNode<HeapObject>, int, TNode<IntPtrT>,
+ WriteBarrierMode);
+template V8_EXPORT_PRIVATE void CodeStubAssembler::CopyRange<Smi>(
+ TNode<HeapObject>, int, TNode<HeapObject>, int, TNode<IntPtrT>,
+ WriteBarrierMode);
+
template <typename TIndex>
void CodeStubAssembler::CopyFixedArrayElements(
ElementsKind from_kind, TNode<FixedArrayBase> from_array,
@@ -20154,7 +20171,9 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
Label check_is_baseline_data(this);
Label check_is_interpreter_data(this);
Label check_is_uncompiled_data(this);
- Label check_is_wasm_function_data(this);
+#if V8_ENABLE_WEBASSEMBLY
+ Label unexpected_wasm_data(this);
+#endif // V8_ENABLE_WEBASSEMBLY
LoadSharedFunctionInfoTrustedDataAndDispatch(
shared_info, &sfi_data_out, data_type_out, &use_untrusted_data,
@@ -20171,8 +20190,11 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
{UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE,
&check_is_uncompiled_data},
#if V8_ENABLE_WEBASSEMBLY
- {WASM_CAPI_FUNCTION_DATA_TYPE, &check_is_wasm_function_data},
- {WASM_EXPORTED_FUNCTION_DATA_TYPE, &check_is_wasm_function_data},
+ // GetSharedFunctionInfoCode is only called by CompileLazy, which Wasm
+ // functions never enter because their wrapper code is installed
+ // directly into the JSDispatchTable at creation time.
+ {WASM_EXPORTED_FUNCTION_DATA_TYPE, &unexpected_wasm_data},
+ {WASM_CAPI_FUNCTION_DATA_TYPE, &unexpected_wasm_data},
#endif // V8_ENABLE_WEBASSEMBLY
});
@@ -20210,14 +20232,6 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
sfi_code = HeapConstantNoHole(BUILTIN_CODE(isolate(), CompileLazy));
Goto(if_compile_lazy ? if_compile_lazy : &done);
-#if V8_ENABLE_WEBASSEMBLY
- // IsWasmFunctionData: Use the wrapper code
- BIND(&check_is_wasm_function_data);
- sfi_code = LoadTrustedPointerFromObject<kCodeIndirectPointerTag>(
- CAST(sfi_data_out.value()), offsetof(WasmFunctionData, wrapper_code_));
- Goto(&done);
-#endif // V8_ENABLE_WEBASSEMBLY
-
BIND(&use_untrusted_data);
{
TNode<Object> untrusted_sfi_data =
@@ -20276,6 +20290,11 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
#endif // V8_ENABLE_WEBASSEMBLY
}
+#if V8_ENABLE_WEBASSEMBLY
+ BIND(&unexpected_wasm_data);
+ Unreachable();
+#endif // V8_ENABLE_WEBASSEMBLY
+
BIND(&unknown_data);
Unreachable();
@@ -21862,9 +21881,9 @@ TNode<ArrayList> CodeStubAssembler::ArrayListEnsureSpace(
GotoIf(Word32Equal(array_length, Uint32Constant(0)), &done);
StoreObjectFieldNoWriteBarrier(new_array, offsetof(ArrayList, length_),
array_length);
- CopyRange(new_array, ArrayList::OffsetOfElementAt(0), array,
- ArrayList::OffsetOfElementAt(0),
- Signed(ChangeUint32ToWord(array_length)));
+ CopyRange<Object>(new_array, ArrayList::OffsetOfElementAt(0), array,
+ ArrayList::OffsetOfElementAt(0),
+ Signed(ChangeUint32ToWord(array_length)));
Goto(&done);
BIND(&overflow);
@@ -21908,8 +21927,8 @@ TNode<FixedArray> CodeStubAssembler::ArrayListElements(TNode<ArrayList> array) {
static constexpr ElementsKind kind = ElementsKind::PACKED_ELEMENTS;
TNode<IntPtrT> length = Signed(ChangeUint32ToWord(ArrayListGetLength(array)));
TNode<FixedArray> elements = CAST(AllocateFixedArray(kind, length));
- CopyRange(elements, FixedArray::OffsetOfElementAt(0), array,
- ArrayList::OffsetOfElementAt(0), length);
+ CopyRange<Object>(elements, FixedArray::OffsetOfElementAt(0), array,
+ ArrayList::OffsetOfElementAt(0), length);
return elements;
}
diff --git a/deps/v8/src/codegen/code-stub-assembler.h b/deps/v8/src/codegen/code-stub-assembler.h
index 968b1710583..004d38e895c 100644
--- a/deps/v8/src/codegen/code-stub-assembler.h
+++ b/deps/v8/src/codegen/code-stub-assembler.h
@@ -2504,6 +2504,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> src_index, TNode<IntPtrT> length,
WriteBarrierMode write_barrier = UPDATE_WRITE_BARRIER);
+ // Copies |length_in_tagged| tagged values from |src_object| + |src_offset| to
+ // |dst_object| + |dst_offset|. Offsets are measured from the start of the
+ // object (use offsetof).
+ //
+ // The elements type |T| may be Object or Smi (the latter ignores mode and
+ // always skips the barrier).
+ template <class T>
void CopyRange(TNode<HeapObject> dst_object, int dst_offset,
TNode<HeapObject> src_object, int src_offset,
TNode<IntPtrT> length_in_tagged,
@@ -4515,12 +4522,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void TailCallJSCode(TNode<Code> code, TNode<Context> context,
TNode<JSFunction> function, TNode<Object> new_target,
TNode<Int32T> arg_count,
- TNode<JSDispatchHandleT> dispatch_handle);
+ TNode<JSDispatchHandleT> dispatch_handle,
+ TNode<Uint16T> expected_parameter_count);
// Same as above, but the code object is loaded from the dispatch table
- // entry and thus the parameter count check is not necessary.
+ // entry. Still checks that the dispatch table entry's parameter count has
+ // not changed. In regular execution, the dispatch entry is kept alive via
+ // the target JSFunction on the stack, so it cannot be reclaimed during a
+ // runtime call. However, with in-sandbox memory corruption, a dispatch
+ // handle may not be kept alive and its entry could be swept and reallocated
+ // with a different parameter count during a GC.
void TailCallJSCode(TNode<Context> context, TNode<JSFunction> function,
TNode<Object> new_target, TNode<Int32T> arg_count,
- TNode<JSDispatchHandleT> dispatch_handle);
+ TNode<JSDispatchHandleT> dispatch_handle,
+ TNode<Uint16T> expected_parameter_count);
// Indicate that this code must support a dynamic parameter count.
//
@@ -5018,6 +5032,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
private:
friend class CodeStubArguments;
+ // Loads one CopyRange element.
+ template <class T>
+ TNode<T> LoadCopyRangeElement(TNode<HeapObject> object,
+ TNode<IntPtrT> offset) {
+ TNode<T> value = LoadReference<T>(Reference{object, offset});
+ if constexpr (std::is_same_v<T, Smi>) CSA_DCHECK(this, TaggedIsSmi(value));
+ return value;
+ }
+
void BigInt64Comparison(Operation op, TNode<Object>& left,
TNode<Object>& right, Label* return_true,
Label* return_false);
diff --git a/deps/v8/src/codegen/compiler.cc b/deps/v8/src/codegen/compiler.cc
index 7918e1548f8..fbcf0d8ba77 100644
--- a/deps/v8/src/codegen/compiler.cc
+++ b/deps/v8/src/codegen/compiler.cc
@@ -723,6 +723,8 @@ void EnsureInfosArrayOnScript(DirectHandle<Script> script,
void UpdateSharedFunctionFlagsAfterCompilation(FunctionLiteral* literal) {
Tagged<SharedFunctionInfo> shared_info = *literal->shared_function_info();
DCHECK_EQ(shared_info->language_mode(), literal->language_mode());
+ DCHECK_EQ(shared_info->syntax_kind(), literal->syntax_kind());
+ DCHECK_EQ(shared_info->kind(), literal->kind());
// These fields are all initialised in ParseInfo from the SharedFunctionInfo,
// and then set back on the literal after parse. Hence, they should already
@@ -2154,7 +2156,7 @@ class ConstantPoolPointerForwarder {
if (!sfi->HasOuterScopeInfo()) return;
Tagged<ScopeInfo> parent =
- sfi->scope_info()->IsEmpty() ? Tagged<ScopeInfo>() : sfi->scope_info();
+ sfi->HasScopeInfo() ? sfi->scope_info() : Tagged<ScopeInfo>();
Tagged<ScopeInfo> outer_info = sfi->GetOuterScopeInfo();
auto it = scope_infos_to_update_.find(outer_info->UniqueIdInScript());
@@ -2379,7 +2381,7 @@ void VerifyCodeMerge(Isolate* isolate, DirectHandle<Script> script) {
}
}
- if (!sfi->scope_info()->IsEmpty()) {
+ if (sfi->HasScopeInfo()) {
scope_info = sfi->scope_info();
} else if (sfi->HasOuterScopeInfo()) {
scope_info = sfi->GetOuterScopeInfo();
@@ -2493,9 +2495,8 @@ void BackgroundMergeTask::BeginMergeInBackground(
// Also push the old_sfi to make sure it stays alive / isn't replaced.
new_compiled_data_for_cached_sfis_.push_back(
{old_sfi_handle, local_heap->NewPersistentHandle(new_sfi)});
- Tagged<ScopeInfo> info = old_sfi->scope_info();
- if (!info->IsEmpty()) {
- new_sfi->SetScopeInfo(info);
+ if (old_sfi->HasScopeInfo()) {
+ new_sfi->SetScopeInfo(old_sfi->scope_info());
} else {
Tagged<ScopeInfo> outer_info = old_sfi->TryGetOuterScopeInfo();
if (!outer_info->IsEmpty()) {
@@ -2525,7 +2526,7 @@ void BackgroundMergeTask::BeginMergeInBackground(
Tagged<SharedFunctionInfo> sfi;
if (TryCast<SharedFunctionInfo>(maybe_old_info.GetHeapObjectAssumeWeak(),
&sfi)) {
- if (sfi->scope_info()->IsEmpty()) {
+ if (!sfi->HasScopeInfo()) {
sfis_without_scope_info_.insert(i);
}
}
diff --git a/deps/v8/src/codegen/heap-object-list.h b/deps/v8/src/codegen/heap-object-list.h
index a65f2c5d4d9..62202b07607 100644
--- a/deps/v8/src/codegen/heap-object-list.h
+++ b/deps/v8/src/codegen/heap-object-list.h
@@ -146,6 +146,7 @@
V(PropertyCellHoleValue, property_cell_hole_value, PropertyCellHole) \
V(HashTableHoleValue, hash_table_hole_value, HashTableHole) \
V(PromiseHoleValue, promise_hole_value, PromiseHole) \
+ V(TdzHoleValue, tdz_hole_value, TdzHole) \
V(then_string, then_string, ThenString) \
V(toJSON_string, toJSON_string, ToJSONString) \
V(toString_string, toString_string, ToStringString) \
diff --git a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
index 0ff1ab0cbb4..cf8c680be93 100644
--- a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
+++ b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
@@ -212,6 +212,15 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
}
}
+void MacroAssembler::StoreTaggedRoot(const MemOperand& destination,
+ RootIndex index) {
+ ASM_CODE_COMMENT(this);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadTaggedRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+}
+
void MacroAssembler::LoadCompressedRoot(Register destination, RootIndex index) {
if (V8_STATIC_ROOTS_BOOL && RootsTable::IsReadOnly(index)) {
li(destination, (int32_t)ReadOnlyRootPtr(index));
@@ -631,6 +640,32 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
MemOperand(scratch, JSDispatchEntry::kCodeObjectOffset));
}
+void MacroAssembler::PushDispatchHandle(Register dispatch_handle,
+ Register scratch1, Register scratch2) {
+ DCHECK(!AreAliased(dispatch_handle, scratch1, scratch2));
+#ifdef V8_ENABLE_SANDBOX
+ AssertZeroExtended(dispatch_handle);
+ LoadParameterCountFromJSDispatchTable(scratch1, dispatch_handle, scratch2);
+ bstrins_d(dispatch_handle, scratch1, 63, 32);
+#endif
+ Push(dispatch_handle);
+ // No need to SmiTag since dispatch handles always look like Smis.
+ static_assert(kJSDispatchHandleShift > 0);
+ AssertSmi(dispatch_handle);
+}
+
+void MacroAssembler::PopDispatchHandle(Register dispatch_handle,
+ Register scratch1, Register scratch2) {
+ DCHECK(!AreAliased(dispatch_handle, scratch1, scratch2));
+ Pop(dispatch_handle);
+#ifdef V8_ENABLE_SANDBOX
+ LoadParameterCountFromJSDispatchTable(scratch1, dispatch_handle, scratch2);
+ bstrpick_d(scratch2, dispatch_handle, 63, 32);
+ bstrpick_d(dispatch_handle, dispatch_handle, 31, 0);
+ SbxCheck(eq, AbortReason::kJSSignatureMismatch, scratch1, Operand(scratch2));
+#endif
+}
+
void MacroAssembler::LoadProtectedPointerField(Register destination,
MemOperand field_operand) {
DCHECK(root_array_available());
@@ -1424,8 +1459,10 @@ void MacroAssembler::Rotr_d(Register rd, Register rj, const Operand& rk) {
}
void MacroAssembler::Alsl_w(Register rd, Register rj, Register rk, uint8_t sa) {
- DCHECK(sa >= 1 && sa <= 31);
- if (sa <= 4) {
+ DCHECK(sa >= 0 && sa <= 31);
+ if (sa == 0) {
+ add_w(rd, rj, rk);
+ } else if (sa <= 4) {
alsl_w(rd, rj, rk, sa);
} else {
UseScratchRegisterScope temps(this);
@@ -1437,8 +1474,10 @@ void MacroAssembler::Alsl_w(Register rd, Register rj, Register rk, uint8_t sa) {
}
void MacroAssembler::Alsl_d(Register rd, Register rj, Register rk, uint8_t sa) {
- DCHECK(sa >= 1 && sa <= 63);
- if (sa <= 4) {
+ DCHECK(sa >= 0 && sa <= 63);
+ if (sa == 0) {
+ add_d(rd, rj, rk);
+ } else if (sa <= 4) {
alsl_d(rd, rj, rk, sa);
} else {
UseScratchRegisterScope temps(this);
@@ -3687,12 +3726,36 @@ void MacroAssembler::BranchShort(Label* L, Condition cond, Register rj,
void MacroAssembler::CompareTaggedAndBranch(Label* label, Condition cond,
Register r1, const Operand& r2,
bool need_link) {
- DCHECK(cond == eq || cond == ne);
if (COMPRESS_POINTERS_BOOL) {
UseScratchRegisterScope temps(this);
Register scratch0 = temps.Acquire();
- Sub_w(scratch0, r1, r2);
- Branch(label, cond, scratch0, Operand(zero_reg), need_link);
+ if (cond == eq || cond == ne) {
+ Sub_w(scratch0, r1, r2);
+ Branch(label, cond, scratch0, Operand(zero_reg), need_link);
+ } else {
+ slli_w(scratch0, r1, 0);
+ if (IsZero(r2)) {
+ Branch(label, cond, scratch0, Operand(zero_reg), need_link);
+ } else {
+ Register scratch1 = temps.Acquire();
+ if (r2.is_reg()) {
+ slli_w(scratch1, r2.rm(), 0);
+ } else {
+ if (RelocInfo::IsFullEmbeddedObject(r2.rmode())) {
+ li(scratch1,
+ Operand(r2.immediate(), RelocInfo::COMPRESSED_EMBEDDED_OBJECT));
+ } else if (RelocInfo::IsCompressedEmbeddedObject(r2.rmode())) {
+ li(scratch1, r2);
+ } else if (RelocInfo::IsNoInfo(r2.rmode())) {
+ LiLower32BitHelper(scratch1, r2);
+ } else {
+ li(scratch1, r2);
+ slli_w(scratch1, scratch1, 0);
+ }
+ }
+ Branch(label, cond, scratch0, Operand(scratch1), need_link);
+ }
+ }
} else {
Branch(label, cond, r1, r2, need_link);
}
@@ -5887,6 +5950,8 @@ void MacroAssembler::CallJSDispatchEntry(JSDispatchHandle dispatch_handle,
Register scratch = s1;
li(kJavaScriptCallDispatchHandleRegister,
Operand(dispatch_handle.value(), RelocInfo::JS_DISPATCH_HANDLE));
+ bstrpick_d(kJavaScriptCallDispatchHandleRegister,
+ kJavaScriptCallDispatchHandleRegister, 31, 0);
LoadEntrypointFromJSDispatchTable(code, kJavaScriptCallDispatchHandleRegister,
scratch);
CHECK_EQ(argument_count,
@@ -6016,10 +6081,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
Push(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
kJavaScriptCallArgCountRegister);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- // No need to SmiTag since dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- AssertSmi(kJavaScriptCallDispatchHandleRegister);
- Push(kJavaScriptCallDispatchHandleRegister);
+ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, a5, a6);
#endif
// Function is also the parameter to the runtime call.
Push(kJavaScriptCallTargetRegister);
@@ -6029,7 +6091,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
// Restore target function, new target, actual argument count and dispatch
// handle.
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- Pop(kJavaScriptCallDispatchHandleRegister);
+ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, a5, a6);
#endif
Pop(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
kJavaScriptCallArgCountRegister);
diff --git a/deps/v8/src/codegen/loong64/macro-assembler-loong64.h b/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
index 7436c20ac4c..7ee25e9a467 100644
--- a/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
+++ b/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
@@ -881,6 +881,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadRoot(Register destination, RootIndex index, Condition cond,
Register src1, const Operand& src2);
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index);
void LoadCompressedRoot(Register destination, RootIndex index);
void LoadMap(Register destination, Register object);
@@ -1142,6 +1143,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadEntrypointAndParameterCountFromJSDispatchTable(
Register entrypoint, Register parameter_count, Register dispatch_handle,
Register scratch);
+ void PushDispatchHandle(Register dispatch_handle, Register scratch1,
+ Register scratch2);
+ void PopDispatchHandle(Register dispatch_handle, Register scratch1,
+ Register scratch2);
// Load a protected pointer field.
void LoadProtectedPointerField(Register destination,
diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
index 73cb3d6573d..13367917f0b 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
@@ -689,6 +689,15 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
LoadRoot(destination, index);
}
+void MacroAssembler::StoreTaggedRoot(const MemOperand& destination,
+ RootIndex index) {
+ ASM_CODE_COMMENT(this);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadTaggedRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+}
+
void MacroAssembler::LoadRoot(Register destination, RootIndex index,
Condition cond) {
DCHECK(cond == al);
@@ -1870,8 +1879,10 @@ void MacroAssembler::LoadWeakValue(Register out, Register in,
CmpS32(in, Operand(kClearedWeakHeapObjectLower32));
beq(target_if_cleared);
- mov(r0, Operand(~kWeakHeapObjectMask));
- and_(out, in, r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(~kWeakHeapObjectMask));
+ and_(out, in, scratch);
}
void MacroAssembler::EmitIncrementCounter(StatsCounter* counter, int value,
@@ -2041,8 +2052,10 @@ void MacroAssembler::AssertUnreachable(AbortReason reason) {
void MacroAssembler::AssertZeroExtended(Register int32_register) {
if (!v8_flags.debug_code) return;
ASM_CODE_COMMENT(this);
- mov(r0, Operand(kMaxUInt32));
- CmpS64(int32_register, r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(kMaxUInt32));
+ CmpS64(int32_register, scratch);
Check(le, AbortReason::k32BitValueInRegisterIsNotZeroExtended);
}
@@ -2219,10 +2232,10 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
int stack_passed_arguments =
CalculateStackPassedWords(num_reg_arguments, num_double_arguments);
int stack_space = kNumRequiredStackFrameSlots;
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
if (frame_alignment > kSystemPointerSize) {
- UseScratchRegisterScope temps(this);
- Register scratch = temps.Acquire();
// Make stack end at alignment and make room for stack arguments
// -- preserving original value of sp.
mr(scratch, sp);
@@ -2238,8 +2251,9 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
}
// Allocate frame with required slots to make ABI work.
- li(r0, Operand::Zero());
- StoreU64WithUpdate(r0, MemOperand(sp, -stack_space * kSystemPointerSize));
+ li(scratch, Operand::Zero());
+ StoreU64WithUpdate(scratch,
+ MemOperand(sp, -stack_space * kSystemPointerSize));
}
void MacroAssembler::MovToFloatParameter(DoubleRegister src) { Move(d1, src); }
@@ -2367,12 +2381,14 @@ void MacroAssembler::CheckPageFlag(
Register scratch, // scratch may be same register as object
int mask, Condition cc, Label* condition_met) {
DCHECK(cc == ne || cc == eq);
- DCHECK(scratch != r0);
ClearRightImm(scratch, object, Operand(kPageSizeBits));
LoadU64(scratch, MemOperand(scratch, MemoryChunk::FlagsOffset()));
- mov(r0, Operand(mask));
- and_(r0, scratch, r0, SetRC);
+ UseScratchRegisterScope temps(this);
+ Register temp = temps.Acquire();
+ DCHECK_NE(scratch, temp);
+ mov(temp, Operand(mask));
+ and_(temp, scratch, temp, SetRC);
if (cc == ne) {
bne(condition_met, cr0);
@@ -4781,7 +4797,8 @@ void MacroAssembler::JumpCodeObject(Register code_object, JumpMode jump_mode) {
void MacroAssembler::CallJSFunction(Register function_object,
uint16_t argument_count) {
Register code = kJavaScriptCallCodeStartRegister;
- Register dispatch_handle = r0;
+ UseScratchRegisterScope temps(this);
+ Register dispatch_handle = temps.Acquire();
LoadU32(
dispatch_handle,
FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
@@ -4792,7 +4809,8 @@ void MacroAssembler::CallJSFunction(Register function_object,
void MacroAssembler::CallJSDispatchEntry(JSDispatchHandle dispatch_handle,
uint16_t argument_count) {
Register code = kJavaScriptCallCodeStartRegister;
- Register dispatch_handle_reg = r0;
+ UseScratchRegisterScope temps(this);
+ Register dispatch_handle_reg = temps.Acquire();
mov(dispatch_handle_reg,
Operand(dispatch_handle.value(), RelocInfo::JS_DISPATCH_HANDLE));
// WARNING: This entrypoint load is only safe because we are storing a
@@ -4811,7 +4829,8 @@ void MacroAssembler::CallJSDispatchEntry(JSDispatchHandle dispatch_handle,
void MacroAssembler::JumpJSFunction(Register function_object,
JumpMode jump_mode) {
Register code = kJavaScriptCallCodeStartRegister;
- Register dispatch_handle = r0;
+ UseScratchRegisterScope temps(this);
+ Register dispatch_handle = temps.Acquire();
LoadU32(
dispatch_handle,
FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
@@ -5074,7 +5093,6 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, bool with_profiling,
Register return_value = r3;
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
- Register scratch2 = r0;
// Allocate HandleScope in callee-saved registers.
// We will need to restore the HandleScope after the call to the API function,
@@ -5088,14 +5106,14 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, bool with_profiling,
// kCArgRegs[0] but that's ok because we start using it only after the C
// call).
DCHECK(!AreAliased(kCArgRegs[0], kCArgRegs[1], kCArgRegs[2], // C args
- scratch, scratch2, prev_next_address_reg, prev_limit_reg));
+ scratch, prev_next_address_reg, prev_limit_reg));
// function_address and thunk_arg might overlap but this function must not
// corrupt them until the call is made (i.e. overlap with return_value is
// fine).
DCHECK(!AreAliased(function_address, // incoming parameters
- scratch, scratch2, prev_next_address_reg, prev_limit_reg));
+ scratch, prev_next_address_reg, prev_limit_reg));
DCHECK(!AreAliased(thunk_arg, // incoming parameters
- scratch, scratch2, prev_next_address_reg, prev_limit_reg));
+ scratch, prev_next_address_reg, prev_limit_reg));
{
ASM_CODE_COMMENT_STRING(masm,
"Allocate HandleScope in callee-save registers.");
@@ -5135,7 +5153,7 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, bool with_profiling,
static_assert(kInterceptedNo == 1 && kInterceptedSize == 4);
static_assert(kInterceptedNo == kNotInterceptedSentinel);
static_assert(kInterceptedYes == 0);
- __ andi(r0, return_value, Operand(1));
+ __ andi(scratch, return_value, Operand(1));
__ b(to_condition(kNotZero), &done_reading_result);
}
@@ -5178,6 +5196,8 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, bool with_profiling,
{
ASM_CODE_COMMENT_STRING(masm,
"Check if the function scheduled an exception.");
+ UseScratchRegisterScope temps2(masm);
+ Register scratch2 = temps2.Acquire();
__ LoadRoot(scratch, RootIndex::kTheHoleValue);
__ LoadU64(scratch2, __ ExternalReferenceAsOperand(
ER::exception_address(isolate), no_reg));
diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
index 709554b7761..4955340befc 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
@@ -602,6 +602,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
}
void LoadRoot(Register destination, RootIndex index, Condition cond);
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index);
void SwapP(Register src, Register dst);
void SwapP(Register src, MemOperand dst);
diff --git a/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc b/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
index a1e8a4adcf6..8fa91106da4 100644
--- a/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
+++ b/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
@@ -156,10 +156,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
Push(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
kJavaScriptCallArgCountRegister);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- // No need to SmiTag since dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- AssertSmi(kJavaScriptCallDispatchHandleRegister);
- Push(kJavaScriptCallDispatchHandleRegister);
+ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, a5, a6);
#endif
// Function is also the parameter to the runtime call.
Push(kJavaScriptCallTargetRegister);
@@ -169,7 +166,7 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
// Restore target function, new target, actual argument count and dispatch
// handle.
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- Pop(kJavaScriptCallDispatchHandleRegister);
+ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, a5, a6);
#endif
Pop(kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
kJavaScriptCallArgCountRegister);
@@ -216,6 +213,13 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
LoadWord(destination,
MemOperand(kRootRegister, RootRegisterOffsetForRootIndex(index)));
}
+void MacroAssembler::StoreTaggedRoot(const MemOperand& destination,
+ RootIndex index) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadTaggedRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+}
void MacroAssembler::LoadCompressedTaggedRoot(Register destination,
RootIndex index) {
#ifdef V8_TARGET_ARCH_RISCV64
@@ -4607,20 +4611,38 @@ void MacroAssembler::CompareTaggedAndBranch(Label* label, Condition cond,
#if V8_TARGET_ARCH_RISCV64
UseScratchRegisterScope temps(this);
Register scratch0 = temps.Acquire();
- SignExtendWord(scratch0, r1);
- if (IsZero(r2)) {
+ if (cond == eq || cond == ne) {
+ // Equality only depends on the low 32 bits, and a 32-bit subtraction
+ // sign-extends its result, so it is zero exactly when those low 32 bits
+ // match. This avoids sign-extending both operands first.
+ if (r2.is_reg()) {
+ Sub32(scratch0, r1, r2);
+ } else if (MustUseReg(r2.rmode())) {
+ // A relocatable immediate (e.g. a Handle<HeapObject>) is a handle
+ // location, not the value to compare against; materialize it first
+ // so the relocation is recorded and the real value is compared.
+ li(scratch0, r2);
+ Sub32(scratch0, r1, scratch0);
+ } else {
+ Sub32(scratch0, r1, Operand(static_cast<int32_t>(r2.immediate())));
+ }
Branch(label, cond, scratch0, Operand(zero_reg));
} else {
- Register scratch1 = temps.Acquire();
- if (r2.is_reg()) {
- SignExtendWord(scratch1, r2.rm());
+ SignExtendWord(scratch0, r1);
+ if (IsZero(r2)) {
+ Branch(label, cond, scratch0, Operand(zero_reg));
} else {
- li(scratch1, r2);
- if (!base::IsInRange(r2.immediate(), 0, 0x7FFFFFFF)) {
- SignExtendWord(scratch1, scratch1);
+ Register scratch1 = temps.Acquire();
+ if (r2.is_reg()) {
+ SignExtendWord(scratch1, r2.rm());
+ } else {
+ li(scratch1, r2);
+ if (!base::IsInRange(r2.immediate(), 0, 0x7FFFFFFF)) {
+ SignExtendWord(scratch1, scratch1);
+ }
}
+ Branch(label, cond, scratch0, Operand(scratch1));
}
- Branch(label, cond, scratch0, Operand(scratch1));
}
#else
UNREACHABLE();
@@ -5876,8 +5898,8 @@ void MacroAssembler::InvokeFunctionCode(
DCHECK_IMPLIES(new_target.is_valid(), new_target == a3);
Register dispatch_handle = kJavaScriptCallDispatchHandleRegister;
- Lw(dispatch_handle,
- FieldMemOperand(function, offsetof(JSFunction, dispatch_handle_)));
+ Load32U(dispatch_handle,
+ FieldMemOperand(function, offsetof(JSFunction, dispatch_handle_)));
// On function call, call into the debugger if necessary.
Label debug_hook, continue_after_hook;
@@ -7653,6 +7675,10 @@ void MacroAssembler::CallJSDispatchEntry(JSDispatchHandle dispatch_handle,
Register scratch = s1;
li(kJavaScriptCallDispatchHandleRegister,
Operand(dispatch_handle.value(), RelocInfo::JS_DISPATCH_HANDLE));
+#ifdef V8_TARGET_ARCH_RISCV64
+ ZeroExtendWord(kJavaScriptCallDispatchHandleRegister,
+ kJavaScriptCallDispatchHandleRegister);
+#endif
LoadEntrypointFromJSDispatchTable(code, kJavaScriptCallDispatchHandleRegister,
scratch);
CHECK_EQ(argument_count,
@@ -7883,6 +7909,34 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
Lhu(parameter_count, MemOperand(scratch, JSDispatchEntry::kCodeObjectOffset));
}
+void MacroAssembler::PushDispatchHandle(Register dispatch_handle,
+ Register scratch1, Register scratch2) {
+ DCHECK(!AreAliased(dispatch_handle, scratch1, scratch2));
+#ifdef V8_ENABLE_SANDBOX
+ AssertZeroExtended(dispatch_handle);
+ LoadParameterCountFromJSDispatchTable(scratch1, dispatch_handle, scratch2);
+ ZeroExtendWord(dispatch_handle, dispatch_handle);
+ slli(scratch1, scratch1, 32);
+ or_(dispatch_handle, dispatch_handle, scratch1);
+#endif
+ Push(dispatch_handle);
+ // No need to SmiTag since dispatch handles always look like Smis.
+ static_assert(kJSDispatchHandleShift > 0);
+ AssertSmi(dispatch_handle);
+}
+
+void MacroAssembler::PopDispatchHandle(Register dispatch_handle,
+ Register scratch1, Register scratch2) {
+ DCHECK(!AreAliased(dispatch_handle, scratch1, scratch2));
+ Pop(dispatch_handle);
+#ifdef V8_ENABLE_SANDBOX
+ LoadParameterCountFromJSDispatchTable(scratch1, dispatch_handle, scratch2);
+ srli(scratch2, dispatch_handle, 32);
+ ZeroExtendWord(dispatch_handle, dispatch_handle);
+ SbxCheck(eq, AbortReason::kJSSignatureMismatch, scratch1, Operand(scratch2));
+#endif
+}
+
void MacroAssembler::LoadTaggedField(const Register& destination,
const MemOperand& field_operand,
Trapper&& trapper) {
diff --git a/deps/v8/src/codegen/riscv/macro-assembler-riscv.h b/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
index 2b127f46762..ec4fa942ff5 100644
--- a/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
+++ b/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
@@ -1195,6 +1195,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Load an object from the root table.
void LoadRoot(Register destination, RootIndex index) final;
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index);
void LoadCompressedTaggedRoot(Register destination, RootIndex index);
void LoadMap(Register destination, Register object);
@@ -1956,6 +1957,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadEntrypointAndParameterCountFromJSDispatchTable(
Register entrypoint, Register parameter_count, Register dispatch_handle,
Register scratch);
+ void PushDispatchHandle(Register dispatch_handle, Register scratch1,
+ Register scratch2);
+ void PopDispatchHandle(Register dispatch_handle, Register scratch1,
+ Register scratch2);
#endif // V8_TARGET_ARCH_RISCV64
// Load a protected pointer field.
void LoadProtectedPointerField(Register destination,
diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.cc b/deps/v8/src/codegen/s390/macro-assembler-s390.cc
index aaac63946a9..53cfe71665a 100644
--- a/deps/v8/src/codegen/s390/macro-assembler-s390.cc
+++ b/deps/v8/src/codegen/s390/macro-assembler-s390.cc
@@ -719,6 +719,15 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
LoadRoot(destination, index);
}
+void MacroAssembler::StoreTaggedRoot(const MemOperand& destination,
+ RootIndex index) {
+ ASM_CODE_COMMENT(this);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadTaggedRoot(scratch, index);
+ StoreTaggedField(scratch, destination);
+}
+
void MacroAssembler::LoadRoot(Register destination, RootIndex index,
Condition) {
if (CanBeImmediate(index)) {
diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.h b/deps/v8/src/codegen/s390/macro-assembler-s390.h
index 8d5e3ea8d0e..70ed43dd102 100644
--- a/deps/v8/src/codegen/s390/macro-assembler-s390.h
+++ b/deps/v8/src/codegen/s390/macro-assembler-s390.h
@@ -280,6 +280,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
}
void LoadRoot(Register destination, RootIndex index, Condition cond);
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(const MemOperand& destination, RootIndex index);
//--------------------------------------------------------------------------
// S390 Macro Assemblers for Instructions
//--------------------------------------------------------------------------
diff --git a/deps/v8/src/codegen/x64/assembler-x64.h b/deps/v8/src/codegen/x64/assembler-x64.h
index 909347e81e1..a92af581041 100644
--- a/deps/v8/src/codegen/x64/assembler-x64.h
+++ b/deps/v8/src/codegen/x64/assembler-x64.h
@@ -3213,6 +3213,164 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
}
}
+#ifdef V8_ENABLE_APX_F
+ // True if the operand can only be encoded with a REX2 prefix, i.e. if it
+ // references one of the extended GPRs r16-r31 -- directly, or as the base or
+ // index register of a memory operand.
+ inline bool needs_rex2_prefix(Register reg) { return reg.bit4(); }
+ inline bool needs_rex2_prefix(Operand op) { return op.rex2(); }
+
+ template <class P1, class P2>
+ bool needs_rex2_prefix(P1 p1, P2 p2) {
+ return needs_rex2_prefix(p1) || needs_rex2_prefix(p2);
+ }
+#endif // V8_ENABLE_APX_F
+
+ // Emits the 0x0F escape byte if the opcode lives in legacy map 1. Only a
+ // legacy REX prefix needs this: a REX2 prefix carries the map in its M0 bit
+ // and must be the last byte before the opcode.
+ inline void emit_legacy_map_escape(Rex2MapID m) {
+ if (m == kRex2Map1) emit(0x0F);
+ }
+
+ // emit_rex2_or_rex[_64|_32](operands..., m) emits everything between the
+ // legacy prefixes and the opcode of an instruction whose opcode lives in
+ // legacy map {m} -- kRex2Map0 for a one-byte opcode, kRex2Map1 for a
+ // 0x0F-escaped one:
+ // - a single REX2 prefix, if any operand references r16-r31. REX2 encodes
+ // the map itself, so it replaces the 0x0F escape byte.
+ // - otherwise the legacy REX prefix, followed by the 0x0F escape byte if
+ // {m} is kRex2Map1.
+ // The caller emits only the opcode, so the prefix and the escape byte cannot
+ // get out of sync. Any legacy prefix (0x66/0xF2/0xF3/segment override) must
+ // already have been emitted; REX and REX2 both come last.
+ //
+ // REX2 has a single map bit, so instructions in the 0x0F38 and 0x0F3A maps
+ // cannot use these helpers at all -- they need a VEX or EVEX encoding to
+ // reach the extended GPRs.
+ //
+ // Unlike the emit_rex_* helpers these do not accept an XMMRegister yet: the
+ // underlying emit_rex2_* emitters only take a GPR in the reg field.
+ void emit_rex2_or_rex(int size, Rex2MapID m) {
+ // Without operands there is no EGPR to encode, so REX2 is never needed.
+ emit_rex(size);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1>
+ void emit_rex2_or_rex(P1 p1, int size, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1)) {
+ if (size == kInt64Size) {
+ emit_rex2_64(p1, m);
+ } else {
+ DCHECK_EQ(size, kInt32Size);
+ emit_rex2_32(p1, m);
+ }
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex(p1, size);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1, class P2>
+ void emit_rex2_or_rex(P1 p1, P2 p2, int size, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1, p2)) {
+ if (size == kInt64Size) {
+ emit_rex2_64(p1, p2, m);
+ } else {
+ DCHECK_EQ(size, kInt32Size);
+ emit_rex2_32(p1, p2, m);
+ }
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex(p1, p2, size);
+ emit_legacy_map_escape(m);
+ }
+
+ void emit_rex2_or_rex_64(Rex2MapID m) {
+ emit_rex_64();
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1>
+ void emit_rex2_or_rex_64(P1 p1, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1)) {
+ emit_rex2_64(p1, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex_64(p1);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1, class P2>
+ void emit_rex2_or_rex_64(P1 p1, P2 p2, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1, p2)) {
+ emit_rex2_64(p1, p2, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex_64(p1, p2);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1>
+ void emit_rex2_or_rex_32(P1 p1, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1)) {
+ emit_rex2_32(p1, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex_32(p1);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1, class P2>
+ void emit_rex2_or_rex_32(P1 p1, P2 p2, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1, p2)) {
+ emit_rex2_32(p1, p2, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_rex_32(p1, p2);
+ emit_legacy_map_escape(m);
+ }
+
+ // As emit_rex2_or_rex_32, but the REX prefix is omitted entirely when it
+ // would be all-zero. Only the REX fallback is optional: a REX2 prefix is
+ // always emitted when an operand needs one.
+ template <class P1>
+ void emit_optional_rex2_or_rex_32(P1 p1, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1)) {
+ emit_rex2_32(p1, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_optional_rex_32(p1);
+ emit_legacy_map_escape(m);
+ }
+
+ template <class P1, class P2>
+ void emit_optional_rex2_or_rex_32(P1 p1, P2 p2, Rex2MapID m) {
+#ifdef V8_ENABLE_APX_F
+ if (needs_rex2_prefix(p1, p2)) {
+ emit_rex2_32(p1, p2, m);
+ return;
+ }
+#endif // V8_ENABLE_APX_F
+ emit_optional_rex_32(p1, p2);
+ emit_legacy_map_escape(m);
+ }
+
// Emit vex prefix
void emit_vex2_byte0() { emit(0xc5); }
inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.cc b/deps/v8/src/codegen/x64/macro-assembler-x64.cc
index 8e69877decb..5143a961697 100644
--- a/deps/v8/src/codegen/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/codegen/x64/macro-assembler-x64.cc
@@ -211,6 +211,16 @@ void MacroAssembler::LoadTaggedRoot(Register destination, RootIndex index) {
movq(destination, RootAsOperand(index));
}
+void MacroAssembler::StoreTaggedRoot(Operand destination, RootIndex index) {
+ if (CanBeImmediate(index)) {
+ StoreTaggedField(destination,
+ Immediate(static_cast<uint32_t>(ReadOnlyRootPtr(index))));
+ return;
+ }
+ LoadTaggedRoot(kScratchRegister, index);
+ StoreTaggedField(destination, kScratchRegister);
+}
+
void MacroAssembler::LoadRoot(Register destination, RootIndex index) {
if (CanBeImmediate(index)) {
DecompressTagged(destination,
@@ -947,6 +957,35 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
JSDispatchEntry::kCodeObjectOffset));
}
+void MacroAssembler::PushDispatchHandle(Register dispatch_handle,
+ Register scratch) {
+ DCHECK(!AreAliased(dispatch_handle, scratch, kScratchRegister));
+#ifdef V8_ENABLE_SANDBOX
+ AssertZeroExtended(dispatch_handle);
+ LoadParameterCountFromJSDispatchTable(scratch, dispatch_handle);
+ shlq(scratch, Immediate(32));
+ orq(dispatch_handle, scratch);
+#endif
+ Push(dispatch_handle);
+ // No need to SmiTag since dispatch handles always look like Smis.
+ static_assert(kJSDispatchHandleShift > 0);
+ AssertSmi(dispatch_handle);
+}
+
+void MacroAssembler::PopDispatchHandle(Register dispatch_handle,
+ Register scratch) {
+ DCHECK(!AreAliased(dispatch_handle, scratch, kScratchRegister));
+ Pop(dispatch_handle);
+#ifdef V8_ENABLE_SANDBOX
+ LoadParameterCountFromJSDispatchTable(scratch, dispatch_handle);
+ movq(kScratchRegister, dispatch_handle);
+ shrq(kScratchRegister, Immediate(32));
+ movl(dispatch_handle, dispatch_handle);
+ cmpq(scratch, kScratchRegister);
+ SbxCheck(equal, AbortReason::kJSSignatureMismatch);
+#endif
+}
+
void MacroAssembler::LoadProtectedPointerField(Register destination,
Operand field_operand) {
DCHECK(root_array_available());
@@ -1428,20 +1467,17 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
SmiTag(kJavaScriptCallArgCountRegister);
Push(kJavaScriptCallArgCountRegister);
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- // No need to SmiTag since dispatch handles always look like Smis.
- static_assert(kJSDispatchHandleShift > 0);
- AssertSmi(kJavaScriptCallDispatchHandleRegister);
- Push(kJavaScriptCallDispatchHandleRegister);
+ PushDispatchHandle(kJavaScriptCallDispatchHandleRegister, rcx);
#endif
// Function is also the parameter to the runtime call.
Push(kJavaScriptCallTargetRegister);
CallRuntime(function_id, 1);
- // Restore target function, new target, actual argument count, and dispatch
+ // Restore target function, new target, actual argument count and dispatch
// handle.
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
- Pop(kJavaScriptCallDispatchHandleRegister);
+ PopDispatchHandle(kJavaScriptCallDispatchHandleRegister, rcx);
#endif
Pop(kJavaScriptCallArgCountRegister);
SmiUntagUnsigned(kJavaScriptCallArgCountRegister);
@@ -3465,21 +3501,25 @@ void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode,
void MacroAssembler::Call(ExternalReference ext) {
// TODO(350324877): can we DCHECK that the sandboxing mode is correct here?
LoadAddress(kScratchRegister, ext);
+ AssertSpAlignedForCall();
call(kScratchRegister);
}
void MacroAssembler::Call(Operand op) {
// TODO(350324877): can we DCHECK that the sandboxing mode is correct here?
if (!CpuFeatures::IsSupported(INTEL_ATOM)) {
+ AssertSpAlignedForCall();
call(op);
} else {
movq(kScratchRegister, op);
+ AssertSpAlignedForCall();
call(kScratchRegister);
}
}
void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
Move(kScratchRegister, destination, rmode);
+ AssertSpAlignedForCall();
call(kScratchRegister);
}
@@ -3493,6 +3533,7 @@ void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
}
DCHECK_EQ(sandboxing_mode(), code_object->sandboxing_mode());
DCHECK(RelocInfo::IsCodeTarget(rmode));
+ AssertSpAlignedForCall();
call(code_object, rmode);
}
@@ -3615,6 +3656,7 @@ void MacroAssembler::LoadCodeInstructionStart(Register destination,
void MacroAssembler::CallCodeObject(Register code_object,
CodeEntrypointTag tag) {
LoadCodeInstructionStart(code_object, code_object, tag);
+ AssertSpAlignedForCall();
call(code_object);
}
@@ -3648,6 +3690,7 @@ void MacroAssembler::CallJSFunction(Register function_object,
// CallJSDispatchEntry below and crbug.com/412398354 for more details.
cmpl(rbx, Immediate(argument_count));
SbxCheck(less_equal, AbortReason::kJSSignatureMismatch);
+ AssertSpAlignedForCall();
call(rcx);
}
@@ -3660,6 +3703,7 @@ void MacroAssembler::CallJSDispatchEntry(JSDispatchHandle dispatch_handle,
LoadEntrypointFromJSDispatchTable(rcx, kJavaScriptCallDispatchHandleRegister);
CHECK_EQ(argument_count,
isolate()->js_dispatch_table().GetParameterCount(dispatch_handle));
+ AssertSpAlignedForCall();
call(rcx);
}
@@ -3720,6 +3764,7 @@ void MacroAssembler::CallWasmCodePointer(Register target,
if (call_jump_mode == CallJumpMode::kTailCall) {
jmp(target_op);
} else {
+ AssertSpAlignedForCall();
call(target_op);
}
}
@@ -3740,9 +3785,11 @@ void MacroAssembler::CallWasmCodePointerNoSignatureCheck(Register target) {
shll(target, Immediate(kNumClearedHighBits));
shrl(target, Immediate(kNumClearedHighBits - kLeftShift));
+ AssertSpAlignedForCall();
call(Operand(kScratchRegister, target, ScaleFactor::times_1, 0));
#else
static_assert(sizeof(wasm::WasmCodePointerTableEntry) == 8);
+ AssertSpAlignedForCall();
call(Operand(kScratchRegister, target, ScaleFactor::times_8, 0));
#endif
}
@@ -4122,6 +4169,13 @@ Immediate MacroAssembler::ClearedValue() const {
}
#ifdef V8_ENABLE_DEBUG_CODE
+
+void MacroAssembler::AssertSpAlignedForCall() {
+ if (v8_flags.enforce_x64_16byte_alignment && v8_flags.debug_code) {
+ CheckStackAlignment();
+ }
+}
+
void MacroAssembler::AssertNotSmi(Register object) {
if (!v8_flags.debug_code) return;
ASM_CODE_COMMENT(this);
diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.h b/deps/v8/src/codegen/x64/macro-assembler-x64.h
index 8f7d00cefdf..0a722ef83e9 100644
--- a/deps/v8/src/codegen/x64/macro-assembler-x64.h
+++ b/deps/v8/src/codegen/x64/macro-assembler-x64.h
@@ -81,6 +81,7 @@ class V8_EXPORT_PRIVATE MacroAssembler
// Operations on roots in the root-array.
Operand RootAsOperand(RootIndex index);
void LoadTaggedRoot(Register destination, RootIndex index);
+ void StoreTaggedRoot(Operand destination, RootIndex index);
void LoadRoot(Register destination, RootIndex index) final;
void LoadRoot(Operand destination, RootIndex index) {
LoadRoot(kScratchRegister, index);
@@ -710,6 +711,13 @@ class V8_EXPORT_PRIVATE MacroAssembler
void CheckStackAlignment();
+ // Wrapper around CheckStackAlignment. This is used at call sites
+ // to enforce rsp is correctly aligned and thus rbp is aligned within
+ // the callee. This function can be removed and usages replaced with
+ // CheckStackAlignment when --enforce-x64-16byte-alignment is enabled
+ // by default.
+ void AssertSpAlignedForCall() NOOP_UNLESS_DEBUG_CODE;
+
void AlignStackPointer();
// Activation support.
@@ -977,6 +985,8 @@ class V8_EXPORT_PRIVATE MacroAssembler
Register dispatch_handle);
void LoadEntrypointAndParameterCountFromJSDispatchTable(
Register entrypoint, Register parameter_count, Register dispatch_handle);
+ void PushDispatchHandle(Register dispatch_handle, Register scratch);
+ void PopDispatchHandle(Register dispatch_handle, Register scratch);
void LoadProtectedPointerField(Register destination, Operand field_operand);
diff --git a/deps/v8/src/compiler/access-builder.cc b/deps/v8/src/compiler/access-builder.cc
index 1b16c5723ff..f5c48b4c6ea 100644
--- a/deps/v8/src/compiler/access-builder.cc
+++ b/deps/v8/src/compiler/access-builder.cc
@@ -413,10 +413,10 @@ FieldAccess AccessBuilder::ForJSGeneratorObjectFunction() {
// static
FieldAccess AccessBuilder::ForJSGeneratorObjectReceiver() {
FieldAccess access = {
- kTaggedBase, offsetof(JSGeneratorObject, receiver_),
- Handle<Name>(), OptionalMapRef(),
- Type::Internal(), MachineType::AnyTagged(),
- kPointerWriteBarrier, "JSGeneratorObjectReceiver"};
+ kTaggedBase, offsetof(JSGeneratorObject, receiver_),
+ Handle<Name>(), OptionalMapRef(),
+ Type::Any(), MachineType::AnyTagged(),
+ kFullWriteBarrier, "JSGeneratorObjectReceiver"};
return access;
}
diff --git a/deps/v8/src/compiler/access-info.cc b/deps/v8/src/compiler/access-info.cc
index a316a723889..94a6fd5caab 100644
--- a/deps/v8/src/compiler/access-info.cc
+++ b/deps/v8/src/compiler/access-info.cc
@@ -807,7 +807,7 @@ PropertyAccessInfo AccessorAccessInfoHelper(
// JS.
return PropertyAccessInfo::Invalid(zone);
}
- if (IsTheHole(cell->value(kRelaxedLoad))) {
+ if (IsTdzHole(cell->value(kRelaxedLoad))) {
// This module has not been fully initialized yet.
return PropertyAccessInfo::Invalid(zone);
}
diff --git a/deps/v8/src/compiler/backend/arm/code-generator-arm.cc b/deps/v8/src/compiler/backend/arm/code-generator-arm.cc
index c9e5ff98cce..bb60c451ec0 100644
--- a/deps/v8/src/compiler/backend/arm/code-generator-arm.cc
+++ b/deps/v8/src/compiler/backend/arm/code-generator-arm.cc
@@ -327,8 +327,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
@@ -1076,12 +1075,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kArchStoreWithWriteBarrier: // Fall through.
case kArchAtomicStoreWithWriteBarrier: {
- RecordWriteMode mode;
- if (arch_opcode == kArchStoreWithWriteBarrier) {
- mode = RecordWriteModeField::decode(instr->opcode());
- } else {
- mode = AtomicStoreRecordWriteModeField::decode(instr->opcode());
- }
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
Register object = i.InputRegister(0);
Register value = i.InputRegister(2);
@@ -4041,8 +4035,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ vldm(ia_w, sp, fp_regs_to_save.first(), fp_regs_to_save.last());
__ ldm(ia_w, sp, regs_to_save);
} else {
@@ -4050,8 +4043,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) __ stop();
}
diff --git a/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc b/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc
index b729592d8b5..908e379da41 100644
--- a/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc
+++ b/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc
@@ -807,12 +807,11 @@ void VisitStoreCommon(InstructionSelector* selector, OpIndex node,
if (!atomic_order) {
code = kArchStoreWithWriteBarrier;
- code |= RecordWriteModeField::encode(record_write_mode);
} else {
code = kArchAtomicStoreWithWriteBarrier;
code |= AtomicMemoryOrderField::encode(*atomic_order);
- code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
}
+ code |= RecordWriteModeField::encode(record_write_mode);
}
InstructionOperand temps[1];
@@ -2938,7 +2937,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
ArmOperandGenerator g(this);
uint32_t val[kSimd128Size / sizeof(uint32_t)];
const Simd128ConstantOp& constant = Cast<Simd128ConstantOp>(node);
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros, avoid emitting code for generic constants.
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
diff --git a/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc b/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc
index 627857e448f..f4efe50f64d 100644
--- a/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc
@@ -552,8 +552,7 @@ class WasmOutOfLineTrap : public OutOfLineCode {
void GenerateCallToTrap(TrapId trap_id) {
gen_->AssembleSourcePosition(instr_);
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
@@ -564,8 +563,7 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
int pc) {
const MemoryAccessMode access_mode = AccessModeField::decode(opcode);
- if (access_mode == kMemoryAccessTrappingMemOutOfBounds ||
- access_mode == kMemoryAccessTrappingNullDereference) {
+ if (access_mode == kMemoryAccessTrapping) {
codegen->RecordTrappingInstruction(pc);
}
}
@@ -1394,8 +1392,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_MRR);
- RecordWriteMode mode =
- AtomicStoreRecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
Register object = i.InputRegister(0);
@@ -1642,6 +1639,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputOperand2_32(1));
}
break;
+ case kArm64Add64_3: {
+ Register low_out = i.OutputRegister(0);
+ bool use_out_high = instr->OutputCount() > 1;
+ if (use_out_high) {
+ Register high_out = i.OutputRegister(1);
+ __ Adds(low_out, i.InputRegister(0), i.InputOperand2_64(1));
+ __ Cset(high_out, hs);
+ __ Adds(low_out, low_out, i.InputOperand64(2));
+ __ Cinc(high_out, high_out, hs);
+ } else {
+ __ Add(low_out, i.InputRegister(0), i.InputOperand2_64(1));
+ __ Add(low_out, low_out, i.InputOperand64(2));
+ }
+ break;
+ }
case kArm64Add128: {
Register low_out = i.OutputRegister(0);
Register high_out = i.OutputRegister(1);
@@ -2652,17 +2664,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Register tag = handle; // Reuse handle for tag
__ Lsr(tag, destination, kTrustedPointerTableTagShift);
- UseScratchRegisterScope scope(masm());
- Register scratch = scope.AcquireX();
- __ Mov(scratch, 0);
if (tag_range.Size() == 1) {
__ Cmp(tag.W(), static_cast<int32_t>(tag_range.first));
- __ CmovX(destination, scratch, ne);
+ __ CzeroX(destination, ne);
} else {
__ Sub(tag.W(), tag.W(), static_cast<int32_t>(tag_range.first));
__ Cmp(tag.W(),
static_cast<int32_t>(tag_range.last - tag_range.first));
- __ CmovX(destination, scratch, hi);
+ __ CzeroX(destination, hi);
}
__ And(destination, destination, kTrustedPointerTablePayloadMask);
@@ -2995,6 +3004,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#undef ASSEMBLE_IEEE754_UNOP
#if V8_ENABLE_WEBASSEMBLY
+#define SIMD_SHIFT_IMM_CASE(Op, Instr) \
+ case Op: { \
+ const int lane_size = LaneSizeBits(LaneSizeField::decode(opcode)); \
+ VectorFormat f = VectorFormatFillQ(lane_size); \
+ DCHECK(instr->InputAt(1)->IsImmediate()); \
+ __ Instr(i.OutputSimd128Register().Format(f), \
+ i.InputSimd128Register(0).Format(f), \
+ i.InputIntFromLaneSize(1, lane_size)); \
+ break; \
+ }
+
#define SIMD_UNOP_CASE(Op, Instr, FORMAT) \
case Op: \
__ Instr(i.OutputSimd128Register().V##FORMAT(), \
@@ -3008,6 +3028,26 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputSimd128Register(0).Format(f)); \
break; \
}
+#define SIMD_LOW_NARROWING_CASE(Op, Instr) \
+ case Op: { \
+ const VectorFormat wide = \
+ VectorFormatFillQ(LaneSizeBits(LaneSizeField::decode(opcode))); \
+ const VectorFormat narrow = VectorFormatHalfWidth(wide); \
+ __ Instr(i.OutputSimd128Register().Format(narrow), \
+ i.InputSimd128Register(0).Format(wide)); \
+ break; \
+ }
+#define SIMD_HIGH_NARROWING_CASE(Op, Instr) \
+ case Op: { \
+ const VectorFormat wide = \
+ VectorFormatFillQ(LaneSizeBits(LaneSizeField::decode(opcode))); \
+ const VectorFormat narrow = VectorFormatHalfWidthDoubleLanes(wide); \
+ const VRegister dst = i.OutputSimd128Register().Format(narrow); \
+ DCHECK_EQ(dst, i.InputSimd128Register(0).Format(narrow)); \
+ DCHECK_NE(dst.code(), i.InputSimd128Register(1).code()); \
+ __ Instr(dst, i.InputSimd128Register(1).Format(wide)); \
+ break; \
+ }
#define SIMD_BINOP_CASE(Op, Instr, FORMAT) \
case Op: \
__ Instr(i.OutputSimd128Register().V##FORMAT(), \
@@ -3097,6 +3137,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputSimd128Register(2).Format(f)); \
break; \
}
+ SIMD_SHIFT_IMM_CASE(kArm64IShl, Shl);
+ SIMD_SHIFT_IMM_CASE(kArm64IShrS, Sshr);
+ SIMD_SHIFT_IMM_CASE(kArm64IShrU, Ushr);
SIMD_BINOP_LANE_SIZE_CASE(kArm64FMin, Fmin);
SIMD_BINOP_LANE_SIZE_CASE(kArm64FMax, Fmax);
SIMD_UNOP_LANE_SIZE_CASE(kArm64FAbs, Fabs);
@@ -3115,6 +3158,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
SIMD_BINOP_LANE_SIZE_CASE(kArm64IMaxU, Umax);
SIMD_DESTRUCTIVE_BINOP_LANE_SIZE_CASE(kArm64Mla, Mla);
SIMD_DESTRUCTIVE_BINOP_LANE_SIZE_CASE(kArm64Mls, Mls);
+ SIMD_LOW_NARROWING_CASE(kArm64Sqxtn, Sqxtn);
+ SIMD_HIGH_NARROWING_CASE(kArm64Sqxtn2, Sqxtn2);
+ SIMD_LOW_NARROWING_CASE(kArm64Sqxtun, Sqxtun);
+ SIMD_HIGH_NARROWING_CASE(kArm64Sqxtun2, Sqxtun2);
case kArm64Sxtl: {
VectorFormat wide =
VectorFormatFillQ(LaneSizeBits(LaneSizeField::decode(opcode)));
@@ -3339,84 +3386,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputSimd128Register(0).Format(src_f), shift_value);
break;
}
- case kArm64IShl: {
- // If shift value is an immediate, we can call Shl, taking the shift
- // value modulo 2^width. Otherwise, emit code to perform the modulus
- // operation, and call Sshl.
- const int lane_size = LaneSizeBits(LaneSizeField::decode(opcode));
- VectorFormat format = VectorFormatFillQ(lane_size);
- if (instr->InputAt(1)->IsImmediate()) {
- __ Shl(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format),
- i.InputIntFromLaneSize(1, lane_size));
- } else {
- UseScratchRegisterScope temps(masm());
- VRegister tmp = temps.AcquireQ();
- Register shift =
- (lane_size == 64) ? temps.AcquireX() : temps.AcquireW();
- int mask = lane_size - 1;
- __ And(shift, i.InputRegister32(1), mask);
- __ Dup(tmp.Format(format), shift);
- __ Sshl(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format), tmp.Format(format));
- }
- break;
- }
- case kArm64IShrS: {
- // If shift value is an immediate, we can call Sshr, taking the shift
- // value modulo 2^width. Otherwise, emit code to perform the modulus
- // operation, and call Sshl, passing in the negative shift value (treated
- // as right shift).
- const int lane_size = LaneSizeBits(LaneSizeField::decode(opcode));
- VectorFormat format = VectorFormatFillQ(lane_size);
- if (instr->InputAt(1)->IsImmediate()) {
- int shift = i.InputIntFromLaneSize(1, lane_size);
- if (shift == lane_size - 1) {
- __ Cmlt(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format), 0);
- } else {
- __ Sshr(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format), shift);
- }
- } else {
- UseScratchRegisterScope temps(masm());
- VRegister tmp = temps.AcquireQ();
- Register shift =
- (lane_size == 64) ? temps.AcquireX() : temps.AcquireW();
- int mask = lane_size - 1;
- __ And(shift, i.InputRegister32(1), mask);
- __ Dup(tmp.Format(format), shift);
- __ Neg(tmp.Format(format), tmp.Format(format));
- __ Sshl(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format), tmp.Format(format));
- }
- break;
- }
- case kArm64IShrU: {
- // If shift value is an immediate, we can call Ushr, taking the shift
- // value modulo 2^width. Otherwise, emit code to perform the modulus
- // operation, and call Ushl, passing in the negative shift value (treated
- // as right shift).
- const int lane_size = LaneSizeBits(LaneSizeField::decode(opcode));
- VectorFormat format = VectorFormatFillQ(lane_size);
- if (instr->InputAt(1)->IsImmediate()) {
- __ Ushr(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format),
- i.InputIntFromLaneSize(1, lane_size));
- } else {
- UseScratchRegisterScope temps(masm());
- VRegister tmp = temps.AcquireQ();
- Register shift =
- (lane_size == 64) ? temps.AcquireX() : temps.AcquireW();
- int mask = lane_size - 1;
- __ And(shift, i.InputRegister32(1), mask);
- __ Dup(tmp.Format(format), shift);
- __ Neg(tmp.Format(format), tmp.Format(format));
- __ Ushl(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format), tmp.Format(format));
- }
- break;
- }
+ SIMD_BINOP_LANE_SIZE_CASE(kArm64SShl, Sshl);
+ SIMD_BINOP_LANE_SIZE_CASE(kArm64UShl, Ushl);
SIMD_BINOP_LANE_SIZE_CASE(kArm64IAdd, Add);
SIMD_BINOP_LANE_SIZE_CASE(kArm64ISub, Sub);
SIMD_CM_G_CASE(kArm64IEq, eq);
@@ -3522,37 +3493,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Smov(i.OutputRegister32(), i.InputSimd128Register(0).Format(f),
i.InputInt8(1));
break;
- }
- case kArm64I16x8SConvertI32x4: {
- VRegister dst = i.OutputSimd128Register(),
- src0 = i.InputSimd128Register(0),
- src1 = i.InputSimd128Register(1);
- UseScratchRegisterScope scope(masm());
- VRegister temp = scope.AcquireV(kFormat4S);
- if (dst == src1) {
- __ Mov(temp, src1.V4S());
- src1 = temp;
- }
- __ Sqxtn(dst.V4H(), src0.V4S());
- __ Sqxtn2(dst.V8H(), src1.V4S());
- break;
}
SIMD_BINOP_LANE_SIZE_CASE(kArm64IAddSatS, Sqadd);
SIMD_BINOP_LANE_SIZE_CASE(kArm64ISubSatS, Sqsub);
- case kArm64I16x8UConvertI32x4: {
- VRegister dst = i.OutputSimd128Register(),
- src0 = i.InputSimd128Register(0),
- src1 = i.InputSimd128Register(1);
- UseScratchRegisterScope scope(masm());
- VRegister temp = scope.AcquireV(kFormat4S);
- if (dst == src1) {
- __ Mov(temp, src1.V4S());
- src1 = temp;
- }
- __ Sqxtun(dst.V4H(), src0.V4S());
- __ Sqxtun2(dst.V8H(), src1.V4S());
- break;
- }
SIMD_BINOP_LANE_SIZE_CASE(kArm64IAddSatU, Uqadd);
SIMD_BINOP_LANE_SIZE_CASE(kArm64ISubSatU, Uqsub);
SIMD_BINOP_CASE(kArm64I16x8Q15MulRSatS, Sqrdmulh, 8H);
@@ -3560,34 +3503,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ I16x8BitMask(i.OutputRegister32(), i.InputSimd128Register(0));
break;
}
- case kArm64I8x16SConvertI16x8: {
- VRegister dst = i.OutputSimd128Register(),
- src0 = i.InputSimd128Register(0),
- src1 = i.InputSimd128Register(1);
- UseScratchRegisterScope scope(masm());
- VRegister temp = scope.AcquireV(kFormat8H);
- if (dst == src1) {
- __ Mov(temp, src1.V8H());
- src1 = temp;
- }
- __ Sqxtn(dst.V8B(), src0.V8H());
- __ Sqxtn2(dst.V16B(), src1.V8H());
- break;
- }
- case kArm64I8x16UConvertI16x8: {
- VRegister dst = i.OutputSimd128Register(),
- src0 = i.InputSimd128Register(0),
- src1 = i.InputSimd128Register(1);
- UseScratchRegisterScope scope(masm());
- VRegister temp = scope.AcquireV(kFormat8H);
- if (dst == src1) {
- __ Mov(temp, src1.V8H());
- src1 = temp;
- }
- __ Sqxtun(dst.V8B(), src0.V8H());
- __ Sqxtun2(dst.V16B(), src1.V8H());
- break;
- }
case kArm64I8x16BitMask: {
VRegister temp = NoVReg;
@@ -3965,8 +3880,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
return kSuccess;
}
+#undef SIMD_SHIFT_IMM_CASE
#undef SIMD_UNOP_CASE
#undef SIMD_UNOP_LANE_SIZE_CASE
+#undef SIMD_LOW_NARROWING_CASE
+#undef SIMD_HIGH_NARROWING_CASE
#undef SIMD_BINOP_CASE
#undef SIMD_BINOP_LANE_SIZE_CASE
#undef SIMD_LOW_BINOP_LANE_SIZE_CASE
@@ -4501,8 +4419,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ PopCPURegList(fp_regs_to_save);
__ PopCPURegList(regs_to_save);
} else {
@@ -4510,8 +4427,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) __ Brk(0);
}
__ Bind(&done);
diff --git a/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h b/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h
index d2eb53ab398..131b08a6e6c 100644
--- a/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h
+++ b/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h
@@ -70,8 +70,6 @@ namespace compiler {
V(Arm64I32x4SConvertF32x4) \
V(Arm64I16x8Q15MulRSatS) \
V(Arm64I16x8BitMask) \
- V(Arm64I8x16SConvertI16x8) \
- V(Arm64I8x16UConvertI16x8) \
V(Arm64I8x16BitMask) \
V(Arm64S128Const) \
V(Arm64S128Dup) \
@@ -105,6 +103,10 @@ namespace compiler {
V(Arm64S128MoveReg) \
V(Arm64V128AnyTrue) \
V(Arm64AllTrue) \
+ V(Arm64Sqxtn) \
+ V(Arm64Sqxtn2) \
+ V(Arm64Sqxtun) \
+ V(Arm64Sqxtun2) \
V(Arm64Sxtl) \
V(Arm64Sxtl2) \
V(Arm64Uxtl) \
@@ -124,6 +126,8 @@ namespace compiler {
V(Arm64IShl) \
V(Arm64IShrS) \
V(Arm64IShrU) \
+ V(Arm64SShl) \
+ V(Arm64UShl) \
V(Arm64IMul) \
V(Arm64I32x4UConvertF32x4) \
V(Arm64I32x4BitMask) \
@@ -137,8 +141,6 @@ namespace compiler {
V(Arm64I32x4TruncSatF64x2UZero) \
V(Arm64IExtractLaneU) \
V(Arm64IExtractLaneS) \
- V(Arm64I16x8SConvertI32x4) \
- V(Arm64I16x8UConvertI32x4) \
V(Arm64Mla) \
V(Arm64Mls) \
V(Arm64FAdd) \
@@ -205,6 +207,7 @@ namespace compiler {
TARGET_ARCH_OPCODE_WITH_MEMORY_ACCESS_MODE_LIST(V) \
V(Arm64Add) \
V(Arm64Add32) \
+ V(Arm64Add64_3) \
V(Arm64Add128) \
V(Arm64Sub128) \
V(Arm64And) \
diff --git a/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc b/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc
index a8840c9b992..40077180be6 100644
--- a/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc
@@ -113,8 +113,6 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kArm64I32x4SConvertF32x4:
case kArm64I16x8Q15MulRSatS:
case kArm64I16x8BitMask:
- case kArm64I8x16SConvertI16x8:
- case kArm64I8x16UConvertI16x8:
case kArm64I8x16BitMask:
case kArm64S128Const:
case kArm64S128Dup:
@@ -147,6 +145,10 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kArm64S128MoveReg:
case kArm64V128AnyTrue:
case kArm64AllTrue:
+ case kArm64Sqxtn:
+ case kArm64Sqxtn2:
+ case kArm64Sqxtun:
+ case kArm64Sqxtun2:
case kArm64Sxtl:
case kArm64Sxtl2:
case kArm64Uxtl:
@@ -166,6 +168,8 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kArm64IShll:
case kArm64IShrS:
case kArm64IShrU:
+ case kArm64SShl:
+ case kArm64UShl:
case kArm64IMul:
case kArm64I32x4UConvertF32x4:
case kArm64I32x4BitMask:
@@ -180,8 +184,6 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kArm64S128ExtractNarrow:
case kArm64IExtractLaneU:
case kArm64IExtractLaneS:
- case kArm64I16x8SConvertI32x4:
- case kArm64I16x8UConvertI32x4:
case kArm64Mla:
case kArm64Mls:
case kArm64FAdd:
@@ -344,6 +346,7 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kArm64Imod32:
case kArm64Umod:
case kArm64Umod32:
+ case kArm64Add64_3:
case kArm64Add128:
case kArm64Sub128:
return ArchInstResource::kIntMulti;
@@ -426,6 +429,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
switch (instr->arch_opcode()) {
case kArm64Add:
case kArm64Add32:
+ case kArm64Add64_3:
case kArm64Add128:
case kArm64Sub128:
case kArm64And:
@@ -653,9 +657,15 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64IShl:
case kArm64IShrS:
case kArm64IShrU:
+ case kArm64SShl:
+ case kArm64UShl:
case kArm64IMul:
case kArm64I64x2BitMask:
case kArm64I32x4SConvertF32x4:
+ case kArm64Sqxtn:
+ case kArm64Sqxtn2:
+ case kArm64Sqxtun:
+ case kArm64Sqxtun2:
case kArm64Sxtl:
case kArm64Sxtl2:
case kArm64Uxtl:
@@ -672,12 +682,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64I32x4TruncSatF64x2UZero:
case kArm64IExtractLaneU:
case kArm64IExtractLaneS:
- case kArm64I16x8SConvertI32x4:
- case kArm64I16x8UConvertI32x4:
case kArm64I16x8Q15MulRSatS:
case kArm64I16x8BitMask:
- case kArm64I8x16SConvertI16x8:
- case kArm64I8x16UConvertI16x8:
case kArm64I8x16BitMask:
case kArm64S128Const:
case kArm64S128Dup:
@@ -1014,6 +1020,8 @@ int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
case kArm64IShll:
case kArm64IShrS:
case kArm64IShrU:
+ case kArm64SShl:
+ case kArm64UShl:
case kArm64FAdd:
case kArm64FSub:
case kArm64FMin:
@@ -1121,6 +1129,10 @@ int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
case kArm64F32x4DemoteF64x2Zero:
case kArm64I32x4SConvertF32x4:
case kArm64I32x4UConvertF32x4:
+ case kArm64Sqxtn:
+ case kArm64Sqxtn2:
+ case kArm64Sqxtun:
+ case kArm64Sqxtun2:
return kSimdConversionLatency;
// These widen/narrow around the conversion, forming a short dependent
@@ -1129,10 +1141,6 @@ int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
case kArm64F64x2ConvertLowI32x4U:
return kSimdConversionChainLatency;
- case kArm64I8x16UConvertI16x8:
- case kArm64I8x16SConvertI16x8:
- case kArm64I16x8SConvertI32x4:
- case kArm64I16x8UConvertI32x4:
case kArm64I32x4TruncSatF64x2SZero:
case kArm64I32x4TruncSatF64x2UZero:
case kArm64F16x8DemoteF64x2Zero:
diff --git a/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc b/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc
index 24d079ce524..6bc3280b70b 100644
--- a/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc
@@ -55,6 +55,13 @@ class Arm64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}
+ InstructionOperand UseUniqueOperand(OpIndex node, ImmediateMode mode) {
+ if (CanBeImmediate(node, mode)) {
+ return UseImmediate(node);
+ }
+ return UseUniqueRegister(node);
+ }
+
bool IsImmediateZero(OpIndex node) {
if (const ConstantOp* constant =
selector()->Get(node).TryCast<ConstantOp>()) {
@@ -220,28 +227,6 @@ void VisitRR(InstructionSelector* selector, InstructionCode opcode,
selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(op.input(0)));
}
-void VisitSimdShiftRRR(InstructionSelector* selector, InstructionCode opcode,
- OpIndex node, LaneSize lane_size) {
- Arm64OperandGenerator g(selector);
- const Operation& op = selector->Get(node);
- DCHECK_EQ(op.input_count, 2);
-
- int64_t constant;
- if (selector->MatchSignedIntegralConstant(op.input(1), &constant)) {
- if (constant % LaneSizeBits(lane_size) == 0) {
- selector->EmitIdentity(node);
- } else {
- selector->Emit(opcode | LaneSizeField::encode(lane_size),
- g.DefineAsRegister(node), g.UseRegister(op.input(0)),
- g.UseImmediate(op.input(1)));
- }
- } else {
- selector->Emit(opcode | LaneSizeField::encode(lane_size),
- g.DefineAsRegister(node), g.UseRegister(op.input(0)),
- g.UseRegister(op.input(1)));
- }
-}
-
void VisitRRI(InstructionSelector* selector, InstructionCode opcode,
OpIndex node) {
Arm64OperandGenerator g(selector);
@@ -264,6 +249,113 @@ void VisitRRI(InstructionSelector* selector, InstructionCode opcode,
g.UseImmediate(op.lane));
}
}
+// If shift value is an immediate, we can call Shl, taking the shift
+// value modulo 2^width. Otherwise, emit code to perform the modulus
+// operation, and call Sshl.
+void VisitSimdShl(InstructionSelector* selector, OpIndex node,
+ LaneSize lane_size) {
+ Arm64OperandGenerator g(selector);
+ const Simd128ShiftOp& op = selector->Cast<Simd128ShiftOp>(node);
+ int64_t constant;
+ if (selector->MatchSignedIntegralConstant(op.shift(), &constant)) {
+ const int amount =
+ static_cast<int>(constant & (LaneSizeBits(lane_size) - 1));
+ if (amount == 0) {
+ selector->EmitIdentity(node);
+ } else if (amount == 1) {
+ selector->Emit(kArm64IAdd | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ g.UseRegister(op.input()));
+ } else {
+ selector->Emit(kArm64IShl | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ g.TempImmediate(amount));
+ }
+ } else {
+ InstructionOperand tempAnd = g.TempRegister();
+ selector->Emit(kArm64And32, tempAnd, g.UseRegister(op.shift()),
+ g.TempImmediate(LaneSizeBits(lane_size) - 1));
+ InstructionOperand tempDup = g.TempSimd128Register();
+ selector->Emit(kArm64ISplat | LaneSizeField::encode(lane_size), tempDup,
+ tempAnd);
+ selector->Emit(kArm64SShl | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ tempDup);
+ }
+}
+
+// If shift value is an immediate, we can call Sshr, taking the shift
+// value modulo 2^width. Otherwise, emit code to perform the modulus
+// operation, and call Sshl, passing in the negative shift value (treated
+// as right shift).
+void VisitSimdShrS(InstructionSelector* selector, OpIndex node,
+ LaneSize lane_size) {
+ Arm64OperandGenerator g(selector);
+ const Simd128ShiftOp& op = selector->Cast<Simd128ShiftOp>(node);
+ int64_t constant;
+ if (selector->MatchSignedIntegralConstant(op.shift(), &constant)) {
+ const int amount =
+ static_cast<int>(constant & (LaneSizeBits(lane_size) - 1));
+ if (amount == 0) {
+ selector->EmitIdentity(node);
+ } else if (amount == LaneSizeBits(lane_size) - 1) {
+ selector->Emit(kArm64ILtS | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()));
+ } else {
+ selector->Emit(kArm64IShrS | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ g.TempImmediate(amount));
+ }
+ } else {
+ InstructionOperand tempAnd = g.TempRegister();
+ selector->Emit(kArm64And32, tempAnd, g.UseRegister(op.shift()),
+ g.TempImmediate(LaneSizeBits(lane_size) - 1));
+ InstructionOperand tempDup = g.TempSimd128Register();
+ selector->Emit(kArm64ISplat | LaneSizeField::encode(lane_size), tempDup,
+ tempAnd);
+ InstructionOperand tempNeg = g.TempSimd128Register();
+ selector->Emit(kArm64INeg | LaneSizeField::encode(lane_size), tempNeg,
+ tempDup);
+ selector->Emit(kArm64SShl | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ tempNeg);
+ }
+}
+
+// If shift value is an immediate, we can call Ushr, taking the shift
+// value modulo 2^width. Otherwise, emit code to perform the modulus
+// operation, and call Ushl, passing in the negative shift value (treated
+// as right shift).
+void VisitSimdShrU(InstructionSelector* selector, OpIndex node,
+ LaneSize lane_size) {
+ Arm64OperandGenerator g(selector);
+ const Simd128ShiftOp& op = selector->Cast<Simd128ShiftOp>(node);
+ int64_t constant;
+ if (selector->MatchSignedIntegralConstant(op.shift(), &constant)) {
+ const int amount =
+ static_cast<int>(constant & (LaneSizeBits(lane_size) - 1));
+ if (amount == 0) {
+ selector->EmitIdentity(node);
+ } else {
+ selector->Emit(kArm64IShrU | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ g.TempImmediate(amount));
+ }
+ } else {
+ InstructionOperand tempAnd = g.TempRegister();
+ selector->Emit(kArm64And32, tempAnd, g.UseRegister(op.shift()),
+ g.TempImmediate(LaneSizeBits(lane_size) - 1));
+ InstructionOperand tempDup = g.TempSimd128Register();
+ selector->Emit(kArm64ISplat | LaneSizeField::encode(lane_size), tempDup,
+ tempAnd);
+ InstructionOperand tempNeg = g.TempSimd128Register();
+ selector->Emit(kArm64INeg | LaneSizeField::encode(lane_size), tempNeg,
+ tempDup);
+ selector->Emit(kArm64UShl | LaneSizeField::encode(lane_size),
+ g.DefineAsRegister(node), g.UseRegister(op.input()),
+ tempNeg);
+ }
+}
namespace {
bool isSimdZero(InstructionSelector* selector, OpIndex node) {
@@ -1113,7 +1205,7 @@ void InstructionSelector::VisitLoadLane(OpIndex node) {
opcode |= LaneSizeField::encode(
LaneSizeFromBits(static_cast<uint8_t>(load.lane_size() * kBitsPerByte)));
if (load.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Arm64OperandGenerator g(this);
@@ -1128,7 +1220,7 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
opcode |= LaneSizeField::encode(
LaneSizeFromBits(static_cast<uint8_t>(store.lane_size() * kBitsPerByte)));
if (store.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Arm64OperandGenerator g(this);
@@ -1146,7 +1238,6 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
void InstructionSelector::VisitLoadTransform(OpIndex node) {
const Simd128LoadTransformOp& op = Cast<Simd128LoadTransformOp>(node);
InstructionCode load_opcode = kArchNop;
- InstructionCode extend_opcode = kArchNop;
bool require_add = false;
switch (op.transform_kind) {
case Simd128LoadTransformOp::TransformKind::k8Splat:
@@ -1170,29 +1261,12 @@ void InstructionSelector::VisitLoadTransform(OpIndex node) {
require_add = true;
break;
case Simd128LoadTransformOp::TransformKind::k8x8S:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Sxtl | LaneSizeField::encode(LaneSize::kL16);
- break;
case Simd128LoadTransformOp::TransformKind::k8x8U:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Uxtl | LaneSizeField::encode(LaneSize::kL16);
- break;
case Simd128LoadTransformOp::TransformKind::k16x4S:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Sxtl | LaneSizeField::encode(LaneSize::kL32);
- break;
case Simd128LoadTransformOp::TransformKind::k16x4U:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Uxtl | LaneSizeField::encode(LaneSize::kL32);
- break;
case Simd128LoadTransformOp::TransformKind::k32x2S:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Sxtl | LaneSizeField::encode(LaneSize::kL64);
- break;
case Simd128LoadTransformOp::TransformKind::k32x2U:
- load_opcode = kArm64LdrD;
- extend_opcode = kArm64Uxtl | LaneSizeField::encode(LaneSize::kL64);
- break;
+ UNREACHABLE();
case Simd128LoadTransformOp::TransformKind::k32Zero:
load_opcode = kArm64LdrS;
break;
@@ -1206,34 +1280,21 @@ void InstructionSelector::VisitLoadTransform(OpIndex node) {
DCHECK(!op.load_kind.maybe_unaligned);
Arm64OperandGenerator g(this);
- InstructionOperand inputs[2];
- InstructionOperand outputs[1];
-
- inputs[0] = g.UseRegister(op.base());
- inputs[1] = g.UseRegister(op.index());
-
- if (extend_opcode == kArchNop) {
- outputs[0] = g.DefineAsRegister(node);
- } else {
- outputs[0] = g.TempSimd128Register();
- }
+ InstructionOperand base = g.UseRegister(op.base());
+ InstructionOperand index = g.UseRegister(op.index());
if (require_add) {
// ld1r uses post-index, so construct address first.
// TODO(v8:9886) If index can be immediate, use vldr without this add.
- inputs[0] = EmitAddBeforeLoadOrStore(this, node, &load_opcode);
- inputs[1] = g.TempImmediate(0);
- load_opcode |= AddressingModeField::encode(kMode_MRI);
+ base = EmitAddBeforeLoadOrStore(this, node, &load_opcode);
+ index = g.TempImmediate(0);
} else {
load_opcode |= AddressingModeField::encode(kMode_MRR);
}
if (op.load_kind.with_trap_handler) {
- load_opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- }
- Emit(load_opcode, 1, outputs, 2, inputs);
- if (extend_opcode != kArchNop) {
- Emit(extend_opcode, g.DefineSameAsFirst(node), outputs[0]);
+ load_opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
+ Emit(load_opcode, g.DefineAsRegister(node), base, index);
}
#endif // V8_ENABLE_SIMD128
@@ -1367,13 +1428,8 @@ void InstructionSelector::VisitLoad(OpIndex node) {
MemoryRepresentation load_rep = load.ts_loaded_rep();
std::tie(opcode, immediate_mode) =
GetLoadOpcodeAndImmediate(load_rep, load.ts_result_rep());
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- if (traps_on_null) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- }
+ if (load.is_trapping()) {
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitLoad(this, node, opcode, immediate_mode, load_rep);
}
@@ -1441,8 +1497,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
code |= RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
InstructionOperand temps[1];
size_t temp_count = 0;
@@ -1522,10 +1578,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
opcode |= AddressingModeField::encode(kMode_MRR);
}
- if (store_view.is_store_trap_on_null()) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Emit(opcode, 0, nullptr, input_count, inputs);
@@ -2650,7 +2704,27 @@ void InstructionSelector::VisitUint64Sub128(OpIndex node) {
}
void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
- UNIMPLEMENTED();
+ Arm64OperandGenerator g(this);
+ InstructionOperand inputs[3];
+ size_t input_count = 0;
+ InstructionOperand outputs[2];
+ size_t output_count = 0;
+ const auto& op = this->Get(node).Cast<Word64Add3Op>();
+
+ inputs[input_count++] = g.UseRegister(op.first());
+ inputs[input_count++] = g.UseOperand(op.second(), kArithmeticImm);
+ inputs[input_count++] = g.UseUniqueOperand(op.third(), kArithmeticImm);
+
+ OptionalOpIndex out_low = FindProjection(node, 0);
+ outputs[output_count++] =
+ g.DefineAsRegister(out_low.valid() ? out_low.value() : node);
+
+ OptionalOpIndex out_high = FindProjection(node, 1);
+ if (out_high.valid() && IsUsed(out_high.value())) {
+ outputs[output_count++] = g.DefineAsRegister(out_high.value());
+ }
+
+ Emit(kArm64Add64_3, output_count, outputs, input_count, inputs);
}
#if V8_ENABLE_SIMD128
@@ -3805,7 +3879,7 @@ void VisitAtomicExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(kMode_MRR) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (CpuFeatures::IsSupported(LSE)) {
InstructionOperand temps[] = {g.TempRegister()};
@@ -3840,7 +3914,7 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(kMode_MRR) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (CpuFeatures::IsSupported(LSE)) {
InstructionOperand temps[] = {g.TempRegister()};
@@ -3914,11 +3988,8 @@ void VisitAtomicLoad(InstructionSelector* selector, OpIndex node,
UNREACHABLE();
}
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- code |= AccessModeField::encode(traps_on_null
- ? kMemoryAccessTrappingNullDereference
- : kMemoryAccessTrappingMemOutOfBounds);
+ if (load.is_trapping()) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
code |=
@@ -3977,7 +4048,7 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
code = kArchAtomicStoreWithWriteBarrier;
- code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
+ code |= RecordWriteModeField::encode(record_write_mode);
}
} else {
switch (rep) {
@@ -4012,10 +4083,8 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
code |= AtomicWidthField::encode(width);
}
- if (store.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_params.kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_params.kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
code |= AddressingModeField::encode(kMode_MRR);
@@ -4039,7 +4108,7 @@ void VisitAtomicBinop(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (CpuFeatures::IsSupported(LSE)) {
@@ -4899,29 +4968,29 @@ void InstructionSelector::VisitInt64AbsWithOverflow(OpIndex node) {
V(I8x16Abs, kArm64IAbs, LaneSize::kL8) \
V(I8x16Neg, kArm64INeg, LaneSize::kL8)
-#define SIMD_SHIFT_OP_LIST(V) \
- V(I64x2Shl, IShl, LaneSize::kL64) \
- V(I32x4Shl, IShl, LaneSize::kL32) \
- V(I16x8Shl, IShl, LaneSize::kL16) \
- V(I8x16Shl, IShl, LaneSize::kL8) \
- V(I64x2ShrS, IShrS, LaneSize::kL64) \
- V(I32x4ShrS, IShrS, LaneSize::kL32) \
- V(I16x8ShrS, IShrS, LaneSize::kL16) \
- V(I8x16ShrS, IShrS, LaneSize::kL8) \
- V(I64x2ShrU, IShrU, LaneSize::kL64) \
- V(I32x4ShrU, IShrU, LaneSize::kL32) \
- V(I16x8ShrU, IShrU, LaneSize::kL16) \
- V(I8x16ShrU, IShrU, LaneSize::kL8)
+#define SIMD_ISHL_OP_LIST(V) \
+ V(I64x2Shl, LaneSize::kL64) \
+ V(I32x4Shl, LaneSize::kL32) \
+ V(I16x8Shl, LaneSize::kL16) \
+ V(I8x16Shl, LaneSize::kL8)
+
+#define SIMD_ISHRS_OP_LIST(V) \
+ V(I64x2ShrS, LaneSize::kL64) \
+ V(I32x4ShrS, LaneSize::kL32) \
+ V(I16x8ShrS, LaneSize::kL16) \
+ V(I8x16ShrS, LaneSize::kL8)
+
+#define SIMD_ISHRU_OP_LIST(V) \
+ V(I64x2ShrU, LaneSize::kL64) \
+ V(I32x4ShrU, LaneSize::kL32) \
+ V(I16x8ShrU, LaneSize::kL16) \
+ V(I8x16ShrU, LaneSize::kL8)
#define SIMD_BINOP_LIST(V) \
V(I32x4Mul, kArm64IMul | LaneSizeField::encode(LaneSize::kL32)) \
- V(I16x8SConvertI32x4, kArm64I16x8SConvertI32x4) \
V(I16x8Mul, kArm64IMul | LaneSizeField::encode(LaneSize::kL16)) \
- V(I16x8UConvertI32x4, kArm64I16x8UConvertI32x4) \
V(I16x8Q15MulRSatS, kArm64I16x8Q15MulRSatS) \
- V(I16x8RelaxedQ15MulRS, kArm64I16x8Q15MulRSatS) \
- V(I8x16SConvertI16x8, kArm64I8x16SConvertI16x8) \
- V(I8x16UConvertI16x8, kArm64I8x16UConvertI16x8)
+ V(I16x8RelaxedQ15MulRS, kArm64I16x8Q15MulRSatS)
#define SIMD_BINOP_LANE_SIZE_LIST(V) \
V(F64x2Min, kArm64FMin, LaneSize::kL64) \
@@ -4991,7 +5060,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
static_assert(sizeof(val) == kSimd128Size);
const Simd128ConstantOp& constant =
this->Get(node).template Cast<Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
Emit(kArm64S128Const, g.DefineAsRegister(node), g.UseImmediate(val[0]),
g.UseImmediate(val[1]), g.UseImmediate(val[2]), g.UseImmediate(val[3]));
}
@@ -5047,7 +5116,7 @@ std::optional<BicImmParam> BicImmConstHelper(const Operation& op,
const int kUint32Immediates = 4;
uint32_t val[kUint32Immediates];
static_assert(sizeof(val) == kSimd128Size);
- memcpy(val, op.Cast<Simd128ConstantOp>().value, kSimd128Size);
+ memcpy(val, op.Cast<Simd128ConstantOp>().value.data(), kSimd128Size);
// If 4 uint32s are not the same, cannot emit Bic
if (!(val[0] == val[1] && val[1] == val[2] && val[2] == val[3])) {
return std::nullopt;
@@ -5344,28 +5413,29 @@ SIMD_UNOP_LIST(SIMD_VISIT_UNOP)
#undef SIMD_VISIT_UNOP
#undef SIMD_UNOP_LIST
-#define SIMD_VISIT_SHIFT_OP(Name, instruction, lane_size) \
- void InstructionSelector::Visit##Name(OpIndex node) { \
- const Simd128ShiftOp& op = Get(node).Cast<Simd128ShiftOp>(); \
- if (op.kind == Simd128ShiftOp::Kind::kI64x2Shl || \
- op.kind == Simd128ShiftOp::Kind::kI32x4Shl || \
- op.kind == Simd128ShiftOp::Kind::kI16x8Shl || \
- op.kind == Simd128ShiftOp::Kind::kI8x16Shl) { \
- if (auto* constant = TryCast<ConstantOp>(op.shift())) { \
- if (constant->word32() == 1) { \
- Arm64OperandGenerator g(this); \
- Emit(kArm64IAdd | LaneSizeField::encode(lane_size), \
- g.DefineAsRegister(node), g.UseRegister(op.input()), \
- g.UseRegister(op.input())); \
- return; \
- } \
- } \
- } \
- VisitSimdShiftRRR(this, kArm64##instruction, node, lane_size); \
- }
-SIMD_SHIFT_OP_LIST(SIMD_VISIT_SHIFT_OP)
-#undef SIMD_VISIT_SHIFT_OP
-#undef SIMD_SHIFT_OP_LIST
+#define SIMD_VISIT_ISHL_OP(Name, LaneSize) \
+ void InstructionSelector::Visit##Name(OpIndex node) { \
+ VisitSimdShl(this, node, LaneSize); \
+ }
+SIMD_ISHL_OP_LIST(SIMD_VISIT_ISHL_OP)
+#undef SIMD_VISIT_ISHL_OP
+#undef SIMD_ISHL_OP_LIST
+
+#define SIMD_VISIT_ISHRS_OP(Name, LaneSize) \
+ void InstructionSelector::Visit##Name(OpIndex node) { \
+ VisitSimdShrS(this, node, LaneSize); \
+ }
+SIMD_ISHRS_OP_LIST(SIMD_VISIT_ISHRS_OP)
+#undef SIMD_VISIT_ISHRS_OP
+#undef SIMD_ISHRS_OP_LIST
+
+#define SIMD_VISIT_ISHRU_OP(Name, LaneSize) \
+ void InstructionSelector::Visit##Name(OpIndex node) { \
+ VisitSimdShrU(this, node, LaneSize); \
+ }
+SIMD_ISHRU_OP_LIST(SIMD_VISIT_ISHRU_OP)
+#undef SIMD_VISIT_ISHRU_OP
+#undef SIMD_ISHRU_OP_LIST
#define SIMD_VISIT_BINOP(Name, instruction) \
void InstructionSelector::Visit##Name(OpIndex node) { \
@@ -5375,6 +5445,23 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP)
#undef SIMD_VISIT_BINOP
#undef SIMD_BINOP_LIST
+#define SIMD_VISIT_INT_NARROWING(Name, Instr, LaneSize) \
+ void InstructionSelector::Visit##Name(OpIndex node) { \
+ Arm64OperandGenerator g(this); \
+ const Simd128BinopOp& op = Cast<Simd128BinopOp>(node); \
+ const InstructionCode lane_size = LaneSizeField::encode(LaneSize); \
+ const InstructionOperand low = g.TempSimd128Register(); \
+ Emit(kArm64##Instr | lane_size, low, g.UseRegister(op.left())); \
+ Emit(kArm64##Instr##2 | lane_size, g.DefineSameAsFirst(node), low, \
+ g.UseRegister(op.right())); \
+ }
+
+SIMD_VISIT_INT_NARROWING(I16x8SConvertI32x4, Sqxtn, LaneSize::kL32)
+SIMD_VISIT_INT_NARROWING(I16x8UConvertI32x4, Sqxtun, LaneSize::kL32)
+SIMD_VISIT_INT_NARROWING(I8x16SConvertI16x8, Sqxtn, LaneSize::kL16)
+SIMD_VISIT_INT_NARROWING(I8x16UConvertI16x8, Sqxtun, LaneSize::kL16)
+#undef SIMD_VISIT_INT_NARROWING
+
#define SIMD_VISIT_BINOP_LANE_SIZE(Name, instruction, LaneSize) \
void InstructionSelector::Visit##Name(OpIndex node) { \
VisitRRR(this, instruction | LaneSizeField::encode(LaneSize), node); \
@@ -5430,13 +5517,13 @@ MulWithDup TryMatchMulWithDup(InstructionSelector* selector, OpIndex node) {
// in a loop, which won't cover the shuffle since they are different basic
// blocks.
if (left.Is<Simd128ShuffleOp>() &&
- SimdShuffle::TryMatchSplat<LANES>(left.Cast<Simd128ShuffleOp>().shuffle,
- &index)) {
+ SimdShuffle::TryMatchSplat<LANES>(
+ left.Cast<Simd128ShuffleOp>().shuffle.data(), &index)) {
dup_node = left.input(index < LANES ? 0 : 1);
input = mul.right();
} else if (right.Is<Simd128ShuffleOp>() &&
SimdShuffle::TryMatchSplat<LANES>(
- right.Cast<Simd128ShuffleOp>().shuffle, &index)) {
+ right.Cast<Simd128ShuffleOp>().shuffle.data(), &index)) {
dup_node = right.input(index < LANES ? 0 : 1);
input = mul.left();
}
@@ -6914,7 +7001,7 @@ void InstructionSelector::VisitSimd128LoadPairDeinterleave(OpIndex node) {
InstructionCode opcode = kArm64S128LoadPairDeinterleave;
opcode |= LaneSizeField::encode(LaneSizeFromBits(load.lane_size()));
if (load.load_kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
OptionalOpIndex first = FindProjection(node, 0);
OptionalOpIndex second = FindProjection(node, 1);
diff --git a/deps/v8/src/compiler/backend/code-generator.cc b/deps/v8/src/compiler/backend/code-generator.cc
index beaf8798909..28faaf10951 100644
--- a/deps/v8/src/compiler/backend/code-generator.cc
+++ b/deps/v8/src/compiler/backend/code-generator.cc
@@ -602,6 +602,10 @@ void CodeGenerator::RecordSafepoint(ReferenceMap* references, int pc_offset) {
}
}
+void CodeGenerator::RecordSafepointWithoutTaggedSlots() {
+ safepoints()->DefineSafepoint(masm());
+}
+
bool CodeGenerator::IsMaterializableFromRoot(Handle<HeapObject> object,
RootIndex* index_return) {
const CallDescriptor* incoming_descriptor =
diff --git a/deps/v8/src/compiler/backend/code-generator.h b/deps/v8/src/compiler/backend/code-generator.h
index bd8b0b23c16..1b5c3165a22 100644
--- a/deps/v8/src/compiler/backend/code-generator.h
+++ b/deps/v8/src/compiler/backend/code-generator.h
@@ -123,6 +123,10 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
// the current pc is used to define the safepoint. Otherwise the provided
// pc_offset is used.
void RecordSafepoint(ReferenceMap* references, int pc_offset = 0);
+ // In special cases (such as stack checks before initializing the frame),
+ // tagged slots are not yet initialized and hence not safe to visit, so any
+ // safepoints should not include them.
+ void RecordSafepointWithoutTaggedSlots();
Zone* zone() const { return zone_; }
MacroAssembler* masm() { return &masm_; }
diff --git a/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc b/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc
index 26fd003e45c..58cdec956a2 100644
--- a/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc
+++ b/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc
@@ -392,8 +392,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ wasm_call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
@@ -1030,10 +1029,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchStoreWithWriteBarrier: // Fall thrugh.
case kArchAtomicStoreWithWriteBarrier: {
- RecordWriteMode mode =
- arch_opcode == kArchStoreWithWriteBarrier
- ? RecordWriteModeField::decode(instr->opcode())
- : AtomicStoreRecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
Register object = i.InputRegister(0);
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
@@ -4261,8 +4257,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
for (size_t i = 0; i < arraysize(wasm::kFpParamRegisters); i++) {
__ Movdqu(wasm::kFpParamRegisters[i], Operand(esp, kSimd128Size * i));
}
@@ -4276,8 +4271,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
__ bind(&done);
diff --git a/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc b/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc
index cd90ecc9698..13979cd4d6f 100644
--- a/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc
+++ b/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc
@@ -1055,9 +1055,7 @@ void VisitStoreCommon(InstructionSelector* selector,
: kArchStoreWithWriteBarrier;
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
- code |= is_atomic
- ? AtomicStoreRecordWriteModeField::encode(record_write_mode)
- : RecordWriteModeField::encode(record_write_mode);
+ code |= RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
if (atomic_order.has_value()) {
@@ -2866,7 +2864,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
uint32_t val[kUint32Immediates];
const Simd128ConstantOp& constant =
this->Get(node).template Cast<Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
@@ -3555,8 +3553,7 @@ void InstructionSelector::VisitI8x16Swizzle(OpIndex node) {
// emit a pshufb.
const Operation& right_op = this->Get(right);
if (auto c = right_op.TryCast<Simd128ConstantOp>()) {
- std::array<uint8_t, kSimd128Size> imms;
- std::memcpy(&imms, c->value, kSimd128Size);
+ std::array<uint8_t, kSimd128Size> imms = c->value;
op |=
MiscField::encode(compiler::SimdSwizzle::AllInRangeOrTopBitSet(imms));
}
diff --git a/deps/v8/src/compiler/backend/instruction-codes.h b/deps/v8/src/compiler/backend/instruction-codes.h
index 49e9b6e0ef3..03359d373ab 100644
--- a/deps/v8/src/compiler/backend/instruction-codes.h
+++ b/deps/v8/src/compiler/backend/instruction-codes.h
@@ -285,11 +285,7 @@ FlagsCondition CommuteFlagsCondition(FlagsCondition condition);
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const FlagsCondition& fc);
-enum MemoryAccessMode {
- kMemoryAccessDirect = 0,
- kMemoryAccessTrappingMemOutOfBounds = 1,
- kMemoryAccessTrappingNullDereference = 2,
-};
+enum MemoryAccessMode { kMemoryAccessDirect = 0, kMemoryAccessTrapping = 1 };
enum class AtomicWidth { kWord32, kWord64 };
@@ -376,23 +372,32 @@ using InstructionCode = uint32_t;
// So, the following instruction types use the MiscField in the following ways:
// -- Atomics
// Field | Bits
-// AtomicWidth | 2
-// AtomicMemoryOrder | 2
-// AtomicStoreRecordWriteMode | 3
-// AccessMode | 2
+// RecordWriteMode | 3
+// AtomicWidth | 1
+// AtomicMemoryOrder | 1
+// AccessMode | 1
+// Undefined | 3
//
-// -- Write barriers
+// -- Non-atomic stores
// Field | Bits
// RecordWriteMode | 3
-// Undefined | 4
-// AccessMode | 2
+// Undefined | 2
+// AccessMode | 1
+// Undefined | 3
+//
+// -- Non-atomic loads
+// Field | Bits
+// Undefined | 5
+// AccessMode | 1
+// Undefined | 3
//
// -- Vectors
// Field | Bits
// LaneSize | 2
// VectorLength | 2
+// Undefined | 1
+// AccessMode | 1
// Undefined | 3
-// AccessMode | 2
//
// -- Deopts
// Field | Bits
@@ -415,39 +420,34 @@ static_assert(
using FlagsModeField = AddressingModeField::Next<FlagsMode, 3>;
using FlagsConditionField = FlagsModeField::Next<FlagsCondition, 5>;
+// Write modes for writes with barrier.
+using RecordWriteModeField = FlagsConditionField::Next<RecordWriteMode, 3>;
// AtomicWidthField is used for the various Atomic opcodes. Only used on 64bit
// architectures. All atomic instructions on 32bit architectures are assumed to
// be 32bit wide.
-using AtomicWidthField = FlagsConditionField::Next<AtomicWidth, 2>;
+using AtomicWidthField = RecordWriteModeField::Next<AtomicWidth, 1>;
// AtomicMemoryOrderField is used for the various Atomic opcodes. This field is
// not used on all architectures. It is used on architectures where the codegen
// for kSeqCst and kAcqRel differ only by emitting fences.
-using AtomicMemoryOrderField = AtomicWidthField::Next<AtomicMemoryOrder, 2>;
-using AtomicStoreRecordWriteModeField =
- AtomicMemoryOrderField::Next<RecordWriteMode, 3>;
-
-// Write modes for writes with barrier.
-using RecordWriteModeField = FlagsConditionField::Next<RecordWriteMode, 3>;
+using AtomicMemoryOrderField = AtomicWidthField::Next<AtomicMemoryOrder, 1>;
+// Denotes whether the instruction needs to emit an accompanying landing pad for
+// the trap handler.
+using AccessModeField = AtomicMemoryOrderField::Next<MemoryAccessMode, 1>;
// LaneSizeField and AccessModeField are helper types to encode/decode a lane
// size, an access mode, or both inside the overlapping MiscField.
using LaneSizeField = FlagsConditionField::Next<LaneSize, 2>;
using VectorLengthField = LaneSizeField::Next<VectorLength, 2>;
-// Denotes whether the instruction needs to emit an accompanying landing pad for
-// the trap handler.
-using AccessModeField =
- AtomicStoreRecordWriteModeField::Next<MemoryAccessMode, 2>;
-
// Since AccessModeField is defined in terms of atomics, this assert ensures it
// does not overlap with other fields it is used with.
-static_assert(AtomicStoreRecordWriteModeField::kLastUsedBit >=
+static_assert(AtomicMemoryOrderField::kLastUsedBit >=
RecordWriteModeField::kLastUsedBit);
#ifdef V8_TARGET_ARCH_X64
-static_assert(AtomicStoreRecordWriteModeField::kLastUsedBit >=
+static_assert(AtomicMemoryOrderField::kLastUsedBit >=
VectorLengthField::kLastUsedBit);
#else
-static_assert(AtomicStoreRecordWriteModeField::kLastUsedBit >=
+static_assert(AtomicMemoryOrderField::kLastUsedBit >=
LaneSizeField::kLastUsedBit);
#endif
diff --git a/deps/v8/src/compiler/backend/instruction-selector.cc b/deps/v8/src/compiler/backend/instruction-selector.cc
index e490345743c..2fe007252df 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.cc
+++ b/deps/v8/src/compiler/backend/instruction-selector.cc
@@ -1067,8 +1067,7 @@ bool InstructionSelector::IsTrappingLoad(turboshaft::OpIndex node) const {
if (!IsLoadOrLoadImmutable(node)) return false;
- bool traps_on_null;
- return LoadView(schedule_, node).is_trapping(&traps_on_null);
+ return LoadView(schedule_, node).is_trapping();
}
void InstructionSelector::AppendDeoptimizeArguments(
@@ -1770,8 +1769,7 @@ void InstructionSelector::VisitLoadTrustedPointer(OpIndex node) {
MemoryAccessMode access_mode = kMemoryAccessDirect;
if (op.kind.with_trap_handler) {
- DCHECK(op.kind.trap_on_null);
- access_mode = kMemoryAccessTrappingNullDereference;
+ access_mode = kMemoryAccessTrapping;
}
InstructionCode code = ArchOpcodeField::encode(kArchLoadTrustedPointer) |
AccessModeField::encode(access_mode);
diff --git a/deps/v8/src/compiler/backend/instruction-selector.h b/deps/v8/src/compiler/backend/instruction-selector.h
index 4aeb35da9ab..edc64bfac4a 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.h
+++ b/deps/v8/src/compiler/backend/instruction-selector.h
@@ -781,28 +781,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final
DCHECK_NOT_NULL(load_);
return load_->result_rep;
}
- bool is_trapping(bool* traps_on_null) const {
- if (kind().with_trap_handler) {
- if (load_) {
- *traps_on_null = load_->kind.trap_on_null;
-#if V8_ENABLE_SIMD128
- } else {
-#if V8_ENABLE_SIMD256
- DCHECK(
- (load_transform_ && !load_transform_->load_kind.trap_on_null) ||
- (load_transform256_ &&
- !load_transform256_->load_kind.trap_on_null));
-#else
- DCHECK(load_transform_);
- DCHECK(!load_transform_->load_kind.trap_on_null);
-#endif // V8_ENABLE_SIMD256
- *traps_on_null = false;
-#endif // V8_ENABLE_SIMD128
- }
- return true;
- }
- return false;
- }
+ bool is_trapping() const { return kind().with_trap_handler; }
bool is_atomic() const { return kind().is_atomic; }
turboshaft::OpIndex base() const {
@@ -940,9 +919,6 @@ class V8_EXPORT_PRIVATE InstructionSelector final
return op_->element_size_log2;
}
- bool is_store_trap_on_null() const {
- return op_->kind.with_trap_handler && op_->kind.trap_on_null;
- }
operator turboshaft::OpIndex() const { return node_; }
@@ -974,7 +950,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final
return true;
}
- const uint8_t* data() const { return op128_->shuffle; }
+ const uint8_t* data() const { return op128_->shuffle.data(); }
turboshaft::OpIndex input(int index) const {
DCHECK_LT(index, op128_->input_count);
diff --git a/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc b/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
index 9bc155f8218..df98f5d89c4 100644
--- a/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
+++ b/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
@@ -268,8 +268,7 @@ class WasmOutOfLineTrap : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
@@ -280,15 +279,7 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
int pc) {
const MemoryAccessMode access_mode = AccessModeField::decode(opcode);
- if ((access_mode == kMemoryAccessTrappingMemOutOfBounds) ||
- (access_mode == kMemoryAccessTrappingNullDereference)) {
- ReferenceMap* reference_map =
- codegen->zone()->New<ReferenceMap>(codegen->zone());
- // The safepoint has to be recorded at the return address of a call. Address
- // we use as the fake return address in the case of the trap handler is the
- // fault address (here `pc`) + 1. Therefore the safepoint here has to be
- // recorded at pc + 1;
- codegen->RecordSafepoint(reference_map, pc + 1);
+ if (access_mode == kMemoryAccessTrapping) {
codegen->RecordTrappingInstruction(pc);
}
}
@@ -1172,8 +1163,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_MRR);
MacroAssembler::BlockTrampolinePoolScope block_trampoline_pool(masm());
- RecordWriteMode mode =
- AtomicStoreRecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
Register object = i.InputRegister(0);
@@ -1397,6 +1387,22 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputOperand(1), scratch);
break;
}
+ case kLoong64Add64_3: {
+ Register low = i.OutputRegister(0);
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ __ Add_d(scratch, i.InputRegister(0), i.InputOperand(1));
+ if (instr->OutputCount() > 1) {
+ Register high = i.OutputRegister(1);
+ __ Sltu(high, scratch, i.InputRegister(0));
+ __ Add_d(low, scratch, i.InputOperand(2));
+ __ Sltu(scratch, low, scratch);
+ __ Add_d(high, high, scratch);
+ } else {
+ __ Add_d(low, scratch, i.InputOperand(2));
+ }
+ break;
+ }
case kLoong64Add128: {
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
@@ -1644,12 +1650,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kLoong64Cmp64:
// Pseudo-instruction used for cmp/branch. No opcode emitted here.
break;
- case kLoong64CheckWord32ComparisonInputs: {
+ case kLoong64CheckWord32SignExtend: {
Register scratch = i.OutputRegister();
__ slli_w(scratch, i.InputRegister(0), 0);
__ Check(eq, AbortReason::kUnexpectedValue, scratch, i.InputRegister(0));
- __ slli_w(scratch, i.InputRegister(1), 0);
- __ Check(eq, AbortReason::kUnexpectedValue, scratch, i.InputRegister(1));
+ if (instr->InputCount() > 1) {
+ __ slli_w(scratch, i.InputRegister(1), 0);
+ __ Check(eq, AbortReason::kUnexpectedValue, scratch,
+ i.InputRegister(1));
+ }
break;
}
case kLoong64Mov:
@@ -5157,8 +5166,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ MultiPopFPUOrLSX(fp_regs_to_save);
__ MultiPop(regs_to_save);
} else {
@@ -5166,8 +5174,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
diff --git a/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h b/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h
index 92396bc25a9..c263af6f3bc 100644
--- a/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h
+++ b/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h
@@ -50,11 +50,12 @@ namespace compiler {
#define TARGET_ARCH_OPCODE_LIST(V) \
TARGET_ARCH_OPCODE_WITH_MEMORY_ACCESS_MODE_LIST(V) \
- V(Loong64CheckWord32ComparisonInputs) \
+ V(Loong64CheckWord32SignExtend) \
V(Loong64Add_d) \
V(Loong64Add_w) \
V(Loong64AddOvf_d) \
V(Loong64AddOvf_w) \
+ V(Loong64Add64_3) \
V(Loong64Add128) \
V(Loong64Sub_d) \
V(Loong64Sub_w) \
diff --git a/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc b/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc
index 735b1d90d80..abafdc9ab6d 100644
--- a/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc
+++ b/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc
@@ -33,6 +33,13 @@ class Loong64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}
+ InstructionOperand UseUniqueOperand(OpIndex node, InstructionCode opcode) {
+ if (CanBeImmediate(node, opcode)) {
+ return UseImmediate(node);
+ }
+ return UseUniqueRegister(node);
+ }
+
bool IsImmediateZero(OpIndex node) {
if (const ConstantOp* constant =
selector()->Get(node).TryCast<ConstantOp>()) {
@@ -517,13 +524,16 @@ void EmitLoad(InstructionSelector* selector, turboshaft::OpIndex node,
const ShiftOp& shift = lhs.Cast<ShiftOp>();
if (int64_t shift_imm;
selector->MatchIntegralWord64Constant(shift.right(), &shift_imm)) {
- auto temp = g.TempRegister();
- selector->Emit(kLoong64Alsl_d, temp, g.UseRegister(shift.left()),
- g.UseRegister(base), g.UseImmediate(shift_imm));
- selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(output.valid() ? output : node), temp,
- g.UseImmediate(add.right()));
- return;
+ int32_t shift_value = static_cast<int32_t>(shift_imm);
+ if (shift_value >= 0 && shift_value <= 4) {
+ auto temp = g.TempRegister();
+ selector->Emit(kLoong64Alsl_d, temp, g.UseRegister(shift.left()),
+ g.UseRegister(base), g.UseImmediate(shift_value));
+ selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
+ g.DefineAsRegister(output.valid() ? output : node),
+ temp, g.UseImmediate(add.right()));
+ return;
+ }
}
}
}
@@ -565,7 +575,7 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
opcode |= LaneSizeField::encode(
LaneSizeFromBits(static_cast<uint8_t>(store.lane_size() * kBitsPerByte)));
if (store.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Loong64OperandGenerator g(this);
@@ -585,7 +595,7 @@ void InstructionSelector::VisitLoadLane(OpIndex node) {
opcode |= LaneSizeField::encode(
LaneSizeFromBits(static_cast<uint8_t>(load.lane_size() * kBitsPerByte)));
if (load.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Loong64OperandGenerator g(this);
@@ -661,7 +671,7 @@ void InstructionSelector::VisitLoadTransform(OpIndex node) {
outputs[0] = g.DefineAsRegister(node);
if (op.load_kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Emit(opcode, 1, outputs, 2, inputs);
}
@@ -799,13 +809,8 @@ void InstructionSelector::VisitLoad(OpIndex node) {
opcode = GetLoadOpcode(load.ts_loaded_rep(), load.ts_result_rep());
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- if (traps_on_null) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- }
+ if (load.is_trapping()) {
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitLoad(this, node, opcode);
@@ -874,8 +879,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
code |= RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
InstructionOperand temps[1];
@@ -926,10 +931,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
return;
}
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (g.CanBeImmediate(index, code)) {
@@ -1400,7 +1403,7 @@ void InstructionSelector::VisitInt32Add(OpIndex node) {
if (int32_t shift_value, constant_left;
MatchIntegralWord32Constant(shift.right(), &shift_value) &&
!MatchIntegralWord32Constant(add.left(), &constant_left)) {
- if (shift_value >= 1 && shift_value <= 4) {
+ if (shift_value >= 0 && shift_value <= 4) {
Emit(kLoong64Alsl_w, g.DefineAsRegister(node),
g.UseRegister(shift.left()), g.UseRegister(add.left()),
g.TempImmediate(shift_value));
@@ -1415,7 +1418,7 @@ void InstructionSelector::VisitInt32Add(OpIndex node) {
if (int32_t shift_value, constant_right;
MatchIntegralWord32Constant(shift.right(), &shift_value) &&
!MatchIntegralWord32Constant(add.right(), &constant_right)) {
- if (shift_value >= 1 && shift_value <= 4) {
+ if (shift_value >= 0 && shift_value <= 4) {
Emit(kLoong64Alsl_w, g.DefineAsRegister(node),
g.UseRegister(shift.left()), g.UseRegister(add.right()),
g.TempImmediate(shift_value));
@@ -1449,7 +1452,7 @@ void InstructionSelector::VisitInt64Add(OpIndex node) {
!MatchIntegralWord64Constant(add.left(), &constant_left)) {
int32_t shift_value = static_cast<int32_t>(shift_imm);
- if (shift_value >= 1 && shift_value <= 4) {
+ if (shift_value >= 0 && shift_value <= 4) {
Emit(kLoong64Alsl_d, g.DefineAsRegister(node),
g.UseRegister(shift.left()), g.UseRegister(add.left()),
g.TempImmediate(shift_value));
@@ -1465,7 +1468,7 @@ void InstructionSelector::VisitInt64Add(OpIndex node) {
MatchIntegralWord64Constant(shift.right(), &shift_imm) &&
!MatchIntegralWord64Constant(add.right(), &constant_right)) {
int32_t shift_value = static_cast<int32_t>(shift_imm);
- if (shift_value >= 1 && shift_value <= 4) {
+ if (shift_value >= 0 && shift_value <= 4) {
Emit(kLoong64Alsl_d, g.DefineAsRegister(node),
g.UseRegister(shift.left()), g.UseRegister(add.right()),
g.TempImmediate(shift_value));
@@ -1537,6 +1540,30 @@ void InstructionSelector::VisitUint64MulHigh(OpIndex node) {
VisitRRR(this, kLoong64Mulh_du, node);
}
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ Loong64OperandGenerator g(this);
+ const auto& op = Get(node).Cast<Word64Add3Op>();
+
+ OptionalV<Word64> out_low = FindProjection(node, 0);
+ OptionalV<Word64> out_high = FindProjection(node, 1);
+
+ InstructionOperand inputs[3];
+ size_t input_count = 0;
+ inputs[input_count++] = g.UseRegister(op.first());
+ inputs[input_count++] = g.UseOperand(op.second(), kLoong64Add_d);
+ inputs[input_count++] = g.UseUniqueOperand(op.third(), kLoong64Add_d);
+
+ InstructionOperand outputs[2];
+ size_t output_count = 0;
+ outputs[output_count++] =
+ g.DefineAsRegister(out_low.valid() ? out_low.value() : node);
+ if (out_high.valid() && IsUsed(out_high.value())) {
+ outputs[output_count++] = g.DefineAsRegister(out_high.value());
+ }
+
+ Emit(kLoong64Add64_3, output_count, outputs, input_count, inputs);
+}
+
void InstructionSelector::VisitInt64Mul(OpIndex node) {
Loong64OperandGenerator g(this);
const WordBinopOp& mul = Get(node).Cast<WordBinopOp>();
@@ -1929,6 +1956,12 @@ void InstructionSelector::VisitChangeInt32ToInt64(OpIndex node) {
EmitLoad(this, change_op.input(), opcode, node);
return;
}
+ if (v8_flags.debug_code) {
+ if (!USE_SIMULATOR_BOOL || !input_op.Is<DidntThrowOp>()) {
+ Emit(kLoong64CheckWord32SignExtend, g.TempRegister(),
+ g.UseRegister(change_op.input()));
+ }
+ }
EmitIdentity(node);
}
@@ -2302,12 +2335,6 @@ static Instruction* VisitCompare(InstructionSelector* selector,
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
}
-#ifdef V8_COMPRESS_POINTERS
- if (opcode == kLoong64Cmp32) {
- return selector->EmitWithContinuation(opcode, 0, nullptr, input_count,
- inputs, cont);
- }
-#endif
return selector->EmitWithContinuation(opcode, 0, nullptr, input_count, inputs,
cont);
}
@@ -2428,8 +2455,10 @@ void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
RootsTable::IsReadOnly(root_index)) {
Tagged_t ptr =
MacroAssemblerBase::ReadOnlyRootPtr(root_index, selector->isolate());
- imm = ptr;
- has_imm = true;
+ if (g.CanBeImmediate(ptr, kLoong64Cmp32Eq)) {
+ imm = ptr;
+ has_imm = true;
+ }
}
}
@@ -2484,7 +2513,7 @@ void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
}
if (v8_flags.debug_code) {
- selector->Emit(kLoong64CheckWord32ComparisonInputs, g.TempRegister(),
+ selector->Emit(kLoong64CheckWord32SignExtend, g.TempRegister(),
g.UseRegister(op.input(0)), g.UseRegister(op.input(1)));
}
Instruction* instr =
@@ -2548,11 +2577,8 @@ void VisitAtomicLoad(InstructionSelector* selector, OpIndex node,
UNREACHABLE();
}
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- code |= AccessModeField::encode(traps_on_null
- ? kMemoryAccessTrappingNullDereference
- : kMemoryAccessTrappingMemOutOfBounds);
+ if (load.is_trapping()) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (g.CanBeImmediate(index, code)) {
@@ -2616,7 +2642,7 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
code = kArchAtomicStoreWithWriteBarrier;
- code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
+ code |= RecordWriteModeField::encode(record_write_mode);
}
} else {
switch (rep) {
@@ -2650,10 +2676,8 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
}
}
- if (store.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_params.kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_params.kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (g.CanBeImmediate(index, code)) {
@@ -2700,7 +2724,7 @@ void VisitAtomicExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs,
arraysize(temps), temps);
@@ -2732,7 +2756,7 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs,
arraysize(temps), temps);
@@ -2764,7 +2788,7 @@ void VisitAtomicBinop(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, 1, outputs, input_count, inputs, 4, temps);
}
@@ -3006,7 +3030,7 @@ void InstructionSelector::VisitWord32Equal(OpIndex node) {
MacroAssemblerBase::ReadOnlyRootPtr(root_index, isolate());
if (g.CanBeImmediate(ptr, kLoong64Cmp32Eq)) {
VisitCompare(this, kLoong64Cmp32Eq, g.UseRegister(left),
- g.TempImmediate(int32_t(ptr)), &cont);
+ g.TempImmediate(static_cast<int32_t>(ptr)), &cont);
return;
}
}
@@ -3571,7 +3595,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
uint32_t val[kUint32Immediates];
const Simd128ConstantOp& constant =
this->Get(node).template Cast<Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
diff --git a/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc b/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
index 750cceb960d..8cddfacc370 100644
--- a/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
+++ b/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
@@ -240,8 +240,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
@@ -902,10 +901,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchStoreWithWriteBarrier: // Fall through.
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_None);
- RecordWriteMode mode =
- arch_opcode == kArchStoreWithWriteBarrier
- ? RecordWriteModeField::decode(instr->opcode())
- : AtomicStoreRecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2);
@@ -1024,6 +1020,22 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ DaddOverflow(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1),
kScratchReg);
break;
+ case kMips64Add64_3: {
+ Register low = i.OutputRegister(0);
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ __ Daddu(scratch, i.InputRegister(0), i.InputOperand(1));
+ if (instr->OutputCount() > 1) {
+ Register high = i.OutputRegister(1);
+ __ Sltu(high, scratch, i.InputRegister(0));
+ __ Daddu(low, scratch, i.InputOperand(2));
+ __ Sltu(scratch, low, scratch);
+ __ Daddu(high, high, scratch);
+ } else {
+ __ Daddu(low, scratch, i.InputOperand(2));
+ }
+ break;
+ }
case kMips64Add128: {
UseScratchRegisterScope temps(masm());
Register scratch = temps.Acquire();
@@ -4342,8 +4354,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) __ stop();
__ bind(&done);
diff --git a/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h b/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h
index ecfb5b2c3a4..27604bcd75d 100644
--- a/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h
+++ b/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h
@@ -16,6 +16,7 @@ namespace compiler {
V(Mips64Add) \
V(Mips64Dadd) \
V(Mips64DaddOvf) \
+ V(Mips64Add64_3) \
V(Mips64Add128) \
V(Mips64Sub) \
V(Mips64Dsub) \
diff --git a/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc b/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc
index d19373e102a..24c96e56f29 100644
--- a/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc
+++ b/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc
@@ -66,6 +66,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kMips64MulHighU:
case kMips64Dadd:
case kMips64DaddOvf:
+ case kMips64Add64_3:
case kMips64Add128:
case kMips64Dclz:
case kMips64Dctz:
diff --git a/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc b/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
index b23b324c393..9be8d54d280 100644
--- a/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
+++ b/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
@@ -32,6 +32,13 @@ class Mips64OperandGenerator final : public OperandGenerator {
return UseRegister(node);
}
+ InstructionOperand UseUniqueOperand(OpIndex node, InstructionCode opcode) {
+ if (CanBeImmediate(node, opcode)) {
+ return UseImmediate(node);
+ }
+ return UseUniqueRegister(node);
+ }
+
// Use the zero register if the node has the immediate value zero, otherwise
// assign a register.
InstructionOperand UseRegisterOrImmediateZero(OpIndex node) {
@@ -763,6 +770,30 @@ void InstructionSelector::VisitUint64MulHigh(OpIndex node) {
VisitRRR(this, kMips64DMulHighU, node);
}
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ Mips64OperandGenerator g(this);
+ const auto& op = Get(node).Cast<Word64Add3Op>();
+
+ OptionalV<Word64> out_low = FindProjection(node, 0);
+ OptionalV<Word64> out_high = FindProjection(node, 1);
+
+ InstructionOperand inputs[3];
+ size_t input_count = 0;
+ inputs[input_count++] = g.UseRegister(op.first());
+ inputs[input_count++] = g.UseOperand(op.second(), kMips64Dadd);
+ inputs[input_count++] = g.UseUniqueOperand(op.third(), kMips64Dadd);
+
+ InstructionOperand outputs[2];
+ size_t output_count = 0;
+ outputs[output_count++] =
+ g.DefineAsRegister(out_low.valid() ? out_low.value() : node);
+ if (out_high.valid() && IsUsed(out_high.value())) {
+ outputs[output_count++] = g.DefineAsRegister(out_high.value());
+ }
+
+ Emit(kMips64Add64_3, output_count, outputs, input_count, inputs);
+}
+
void InstructionSelector::VisitInt64Mul(OpIndex node) {
// TODO(MIPS_dev): May could be optimized like in Turbofan.
VisitBinop(this, node, kMips64Dmul, true, kMips64Dmul);
@@ -1834,7 +1865,7 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
size_t const temp_count = arraysize(temps);
code = kArchAtomicStoreWithWriteBarrier;
- code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
+ code |= RecordWriteModeField::encode(record_write_mode);
selector->Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
switch (rep) {
diff --git a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
index 621be2d3bce..fa085daf2a5 100644
--- a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
@@ -301,8 +301,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
@@ -3287,8 +3286,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ MultiPopF64AndV128(fp_regs_to_save, simd128_regs_to_save);
__ MultiPop(regs_to_save);
} else {
@@ -3296,8 +3294,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) __ stop();
}
diff --git a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
index 7f20bd01fa2..71432843293 100644
--- a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
@@ -2728,7 +2728,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
uint32_t val[kSimd128Size / sizeof(uint32_t)];
const Simd128ConstantOp& constant =
this->Get(node).template Cast<Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros, avoid emitting code for generic constants.
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
diff --git a/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc b/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
index 28c7bf6ab86..fb1c0f6e1c2 100644
--- a/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
+++ b/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
@@ -15,6 +15,7 @@
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
#include "src/heap/mutable-page.h"
+#include "src/objects/code-inl.h"
#include "src/objects/js-function-inl.h"
#include "src/objects/shared-function-info-inl.h"
#include "src/sandbox/js-dispatch-table-inl.h"
@@ -358,8 +359,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
@@ -411,20 +411,6 @@ Condition FlagsConditionToConditionTst(FlagsCondition condition) {
}
UNREACHABLE();
}
-#if V8_TARGET_ARCH_RISCV64
-Condition FlagsConditionToConditionOvf(FlagsCondition condition) {
- switch (condition) {
- case kOverflow:
- return ne;
- case kNotOverflow:
- return eq;
- default:
- break;
- }
- UNREACHABLE();
-}
-#endif
-
FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate,
FlagsCondition condition) {
switch (condition) {
@@ -539,8 +525,7 @@ class WasmOutOfLineTrap : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
@@ -551,8 +536,7 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
int pc) {
const MemoryAccessMode access_mode = AccessModeField::decode(opcode);
- if (access_mode == kMemoryAccessTrappingMemOutOfBounds ||
- access_mode == kMemoryAccessTrappingNullDereference) {
+ if (access_mode == kMemoryAccessTrapping) {
codegen->RecordTrappingInstruction(pc);
}
}
@@ -683,8 +667,8 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
__ sync(); \
} while (0)
-#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(load_linked, \
- store_conditional) \
+#define ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER( \
+ load_linked, store_conditional, expect_value) \
do { \
Label compareExchange; \
Label exit; \
@@ -693,9 +677,8 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
__ bind(&compareExchange); \
__ load_linked(i.OutputRegister(0), MemOperand(i.TempRegister(0), 0), \
trapper); \
- DCHECK_NE(i.InputRegister(2), i.OutputRegister(0)); \
- __ BranchShort(&exit, ne, i.InputRegister(2), \
- Operand(i.OutputRegister(0))); \
+ DCHECK_NE(expect_value, i.OutputRegister(0)); \
+ __ BranchShort(&exit, ne, expect_value, Operand(i.OutputRegister(0))); \
__ Move(i.TempRegister(2), i.InputRegister(3)); \
__ store_conditional(i.TempRegister(2), MemOperand(i.TempRegister(0), 0)); \
__ BranchShort(&compareExchange, ne, i.TempRegister(2), \
@@ -725,10 +708,10 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
trapper); \
__ ExtractBits(i.OutputRegister(0), i.TempRegister(2), i.TempRegister(1), \
size, sign_extend); \
- __ ExtractBits(i.InputRegister(2), i.InputRegister(2), 0, size, \
+ __ ExtractBits(i.TempRegister(3), i.InputRegister(2), 0, size, \
sign_extend); \
- DCHECK_NE(i.InputRegister(2), i.OutputRegister(0)); \
- __ BranchShort(&exit, ne, i.InputRegister(2), \
+ DCHECK_NE(i.TempRegister(3), i.OutputRegister(0)); \
+ __ BranchShort(&exit, ne, i.TempRegister(3), \
Operand(i.OutputRegister(0))); \
__ InsertBits(i.TempRegister(2), i.InputRegister(3), i.TempRegister(1), \
size); \
@@ -799,6 +782,7 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
Condition cc = FlagsConditionToConditionCmp(condition);
Register left = i.InputRegister(0);
Operand right = i.InputOperand(1);
+ UseScratchRegisterScope temps(masm());
if (instr->arch_opcode() == kRiscvCmpZero ||
instr->arch_opcode() == kRiscvCmpZero32) {
right = Operand(zero_reg);
@@ -806,6 +790,15 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
instr->arch_opcode() == kRiscvTst64) {
left = kScratchReg;
right = Operand(zero_reg);
+#if V8_TARGET_ARCH_RISCV64
+ } else if (instr->arch_opcode() == kRiscvCmp32Eq) {
+ // Only the low 32 bits matter; Sub32 sign-extends its result, so it can
+ // be compared directly against zero.
+ Register scratch = temps.Acquire();
+ __ Sub32(scratch, i.InputRegister(0), i.InputOperand(1));
+ left = scratch;
+ right = Operand(zero_reg);
+#endif
} else {
DCHECK(instr->arch_opcode() == kRiscvCmp32 ||
instr->arch_opcode() == kRiscvCmp);
@@ -967,12 +960,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
};
switch (arch_opcode) {
case kArchCallCodeObject: {
+ CodeEntrypointTag tag =
+ i.InputCodeEntrypointTag(instr->CodeEnrypointTagInputIndex());
if (instr->InputAt(0)->IsImmediate()) {
- __ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
+ Handle<Code> code = i.InputCode(0);
+ // TODO(ishell, http://crbug.com/435630464): move this check to
+ // MacroAssembler::Call().
+ SBXCHECK_EQ(code->entrypoint_tag(), tag);
+ __ Call(code, RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
- CodeEntrypointTag tag =
- i.InputCodeEntrypointTag(instr->CodeEnrypointTagInputIndex());
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
@@ -1013,12 +1010,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kArchTailCallCodeObject: {
+ CodeEntrypointTag tag =
+ i.InputCodeEntrypointTag(instr->CodeEnrypointTagInputIndex());
if (instr->InputAt(0)->IsImmediate()) {
- __ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
+ Handle<Code> code = i.InputCode(0);
+ // TODO(ishell, http://crbug.com/435630464): move this check to
+ // MacroAssembler::Jump().
+ SBXCHECK_EQ(code->entrypoint_tag(), tag);
+ __ Jump(code, RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputOrZeroRegister(0);
- CodeEntrypointTag tag =
- i.InputCodeEntrypointTag(instr->CodeEnrypointTagInputIndex());
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
@@ -1523,6 +1524,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputOperand(1), kScratchReg);
break;
#if V8_TARGET_ARCH_RISCV64
+ case kRiscvAddOvf32:
+ if (instr->InputAt(1)->IsImmediate()) {
+ __ Add32(i.OutputRegister(), i.InputOrZeroRegister(0),
+ i.InputOperand(1));
+ } else {
+ __ AddOverflow32(i.OutputRegister(), i.InputOrZeroRegister(0),
+ i.InputOperand(1), kScratchReg);
+ }
+ break;
+ case kRiscvSubOvf32:
+ if (instr->InputAt(1)->IsImmediate()) {
+ __ Sub32(i.OutputRegister(), i.InputOrZeroRegister(0),
+ i.InputOperand(1));
+ } else {
+ __ SubOverflow32(i.OutputRegister(), i.InputOrZeroRegister(0),
+ i.InputOperand(1), kScratchReg);
+ }
+ break;
case kRiscvAdd64:
__ AddWord(i.OutputRegister(), i.InputOrZeroRegister(0),
i.InputOperand(1));
@@ -1533,8 +1552,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvAdd128: {
Register out_low = i.OutputRegister(0);
Register out_high = i.OutputRegister(1);
+ DCHECK(!AreAliased(out_low, out_high, i.InputRegister(0)));
__ AddWord(out_low, i.InputRegister(0), i.InputOperand(1));
- __ Sltu(kScratchReg, out_low, i.InputOperand(1));
+ __ Sltu(kScratchReg, out_low, i.InputRegister(0));
__ AddWord(out_high, i.InputRegister(2), i.InputOperand(3));
__ AddWord(out_high, out_high, kScratchReg);
break;
@@ -1758,6 +1778,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvCmp:
#ifdef V8_TARGET_ARCH_RISCV64
case kRiscvCmp32:
+ case kRiscvCmp32Eq:
case kRiscvCmpZero32:
#endif
// Pseudo-instruction used for cmp/branch. No opcode emitted here.
@@ -2594,9 +2615,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
switch (AtomicWidthField::decode(opcode)) {
case AtomicWidth::kWord32:
#if V8_TARGET_ARCH_RISCV64
- __ SignExtendWord(i.InputRegister(2), i.InputRegister(2));
+ __ SignExtendWord(i.TempRegister(1), i.InputRegister(2));
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc, i.TempRegister(1));
+#else
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc, i.InputRegister(2));
#endif
- ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc);
break;
#if V8_TARGET_ARCH_RISCV64
case AtomicWidth::kWord64:
@@ -2666,7 +2689,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kRiscvWord64AtomicCompareExchangeUint64:
- ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd);
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Lld, Scd, i.InputRegister(2));
break;
#define ATOMIC_BINOP_CASE(op, inst32, inst64, amoinst32, amoinst64) \
case kAtomic##op##Int8: \
@@ -2724,7 +2747,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#undef ATOMIC_BINOP_CASE
#elif V8_TARGET_ARCH_RISCV32
case kAtomicCompareExchangeWithWriteBarrier: {
- ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc);
+ ASSEMBLE_ATOMIC_COMPARE_EXCHANGE_INTEGER(Ll, Sc, i.InputRegister(2));
if (v8_flags.disable_write_barriers) break;
// Emit the write barrier.
@@ -4757,40 +4780,49 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
Condition cc = FlagsConditionToConditionTst(condition);
__ Branch(tlabel, cc, kScratchReg, Operand(zero_reg));
#if V8_TARGET_ARCH_RISCV64
- } else if (instr->arch_opcode() == kRiscvAdd32 ||
- instr->arch_opcode() == kRiscvSub32) {
+ } else if (instr->arch_opcode() == kRiscvAddOvf32 ||
+ instr->arch_opcode() == kRiscvSubOvf32) {
if (instr->InputAt(1)->IsImmediate()) {
DCHECK_NE(i.OutputRegister(), i.InputRegister(0));
int64_t imm = i.ToConstant(instr->InputAt(1)).ToInt64();
- bool is_add = (instr->arch_opcode() == kRiscvAdd32);
+ bool is_add = (instr->arch_opcode() == kRiscvAddOvf32);
// Define mapping from {is_add, imm < 0, is_overflow} to branch condition.
static const Condition cond_map[2][2][2] = {
{
- /* kRiscvAdd64 */
+ /* kRiscvAddOvf32 */
{lt, ge}, // imm>=0: [kOverflow, !kOverflow]
{gt, le} // imm<0: [kOverflow, !kOverflow]
},
{
- /* kRiscvSub64 */
+ /* kRiscvSubOvf32 */
{gt, le}, // imm>=0: [kOverflow, !kOverflow]
{lt, ge} // imm<0: [kOverflow, !kOverflow]
}};
bool is_overflow = (condition == kOverflow);
if (imm != 0) {
Condition cc = cond_map[is_add][imm < 0][is_overflow];
- __ Branch(tlabel, cc, i.OutputRegister(), Operand(i.InputRegister(0)));
+ // The overflow check compares the sign-extended 32-bit result against
+ // the left input. 32-bit producers may leave dirty upper bits in the
+ // input register, so sign-extend it before the 64-bit comparison.
+ __ SignExtendWord(kScratchReg, i.InputRegister(0));
+ __ Branch(tlabel, cc, i.OutputRegister(), Operand(kScratchReg));
} else if (!is_overflow) {
__ Branch(tlabel);
}
return;
}
- UNREACHABLE();
- } else if (instr->arch_opcode() == kRiscvAdd64 ||
- instr->arch_opcode() == kRiscvSub64) {
- Condition cc = FlagsConditionToConditionOvf(condition);
- __ Sra64(kScratchReg, i.OutputRegister(), 32);
- __ Sra32(kScratchReg2, i.OutputRegister(), 31);
- __ Branch(tlabel, cc, kScratchReg2, Operand(kScratchReg));
+ DCHECK(instr->InputAt(1)->IsRegister());
+ switch (condition) {
+ // Overflow occurs if the overflow register is negative.
+ case kOverflow:
+ __ Branch(tlabel, lt, kScratchReg, Operand(zero_reg));
+ break;
+ case kNotOverflow:
+ __ Branch(tlabel, ge, kScratchReg, Operand(zero_reg));
+ break;
+ default:
+ UNSUPPORTED_COND(instr->arch_opcode(), condition);
+ }
#endif
} else if (instr->arch_opcode() == kRiscvAddOvfWord ||
instr->arch_opcode() == kRiscvSubOvfWord) {
@@ -4824,6 +4856,15 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
UNSUPPORTED_COND(instr->arch_opcode(), condition);
}
#if V8_TARGET_ARCH_RISCV64
+ } else if (instr->arch_opcode() == kRiscvCmp32Eq) {
+ // Sub32 only looks at the low 32 bits and sign-extends its result, so
+ // comparing it against zero is a valid (and cheaper) equality test.
+ Condition cc = FlagsConditionToConditionCmp(condition);
+ DCHECK(cc == eq || cc == ne);
+ UseScratchRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ __ Sub32(scratch, i.InputRegister(0), i.InputOperand(1));
+ __ Branch(tlabel, cc, scratch, Operand(zero_reg));
} else if (instr->arch_opcode() == kRiscvCmp ||
instr->arch_opcode() == kRiscvCmp32) {
#elif V8_TARGET_ARCH_RISCV32
@@ -4949,39 +4990,43 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
#if V8_TARGET_ARCH_RISCV64
- } else if (instr->arch_opcode() == kRiscvAdd32 ||
- instr->arch_opcode() == kRiscvSub32) {
+ } else if (instr->arch_opcode() == kRiscvAddOvf32 ||
+ instr->arch_opcode() == kRiscvSubOvf32) {
if (instr->InputAt(1)->IsImmediate()) {
DCHECK_NE(i.OutputRegister(), i.InputRegister(0));
int64_t imm = i.ToConstant(instr->InputAt(1)).ToInt64();
- bool is_add = (instr->arch_opcode() == kRiscvAdd32);
+ bool is_add = (instr->arch_opcode() == kRiscvAddOvf32);
if (imm != 0) {
+ // The overflow check compares the sign-extended 32-bit result against
+ // the left input. 32-bit producers may leave dirty upper bits in the
+ // input register, so sign-extend it before the 64-bit comparison.
+ __ SignExtendWord(kScratchReg, i.InputRegister(0));
if (is_add) {
if (imm > 0) {
if (condition != kNotOverflow) {
- __ Slt(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Slt(result, i.OutputRegister(), Operand(kScratchReg));
} else {
- __ Sge(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sge(result, i.OutputRegister(), Operand(kScratchReg));
}
} else {
if (condition != kNotOverflow) {
- __ Sgt(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sgt(result, i.OutputRegister(), Operand(kScratchReg));
} else {
- __ Sle(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sle(result, i.OutputRegister(), Operand(kScratchReg));
}
}
} else {
if (imm > 0) {
if (condition != kNotOverflow) {
- __ Sgt(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sgt(result, i.OutputRegister(), Operand(kScratchReg));
} else {
- __ Sle(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sle(result, i.OutputRegister(), Operand(kScratchReg));
}
} else {
if (condition != kNotOverflow) {
- __ Slt(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Slt(result, i.OutputRegister(), Operand(kScratchReg));
} else {
- __ Sge(result, i.OutputRegister(), Operand(i.InputRegister(0)));
+ __ Sge(result, i.OutputRegister(), Operand(kScratchReg));
}
}
}
@@ -4994,16 +5039,11 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
}
- UNREACHABLE();
- } else if (instr->arch_opcode() == kRiscvAdd64 ||
- instr->arch_opcode() == kRiscvSub64) {
- // Check for overflow creates 1 or 0 for result.
- __ Srl64(kScratchReg, i.OutputRegister(), 63);
- __ Srl32(kScratchReg2, i.OutputRegister(), 31);
- __ Xor(result, kScratchReg, kScratchReg2);
- // Toggle result for not overflow.
+ // Overflow occurs if the overflow register is negative.
if (condition == kNotOverflow) {
- __ Xor(result, result, 1);
+ __ Sge(result, kScratchReg, zero_reg);
+ } else {
+ __ Slt(result, kScratchReg, zero_reg);
}
return;
#endif
@@ -5022,7 +5062,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
__ Sgtu(result, kScratchReg, zero_reg);
#if V8_TARGET_ARCH_RISCV64
} else if (instr->arch_opcode() == kRiscvCmp ||
- instr->arch_opcode() == kRiscvCmp32) {
+ instr->arch_opcode() == kRiscvCmp32 ||
+ instr->arch_opcode() == kRiscvCmp32Eq) {
#elif V8_TARGET_ARCH_RISCV32
} else if (instr->arch_opcode() == kRiscvCmp) {
#endif
@@ -5030,6 +5071,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
Register left = i.InputRegister(0);
Operand right = i.InputOperand(1);
#if V8_TARGET_ARCH_RISCV64
+ if (instr->arch_opcode() == kRiscvCmp32Eq) {
+ // Only the low 32 bits matter for equality; Sub32 sign-extends its
+ // result, so a zero test on it is exact.
+ DCHECK(cc == eq || cc == ne);
+ __ Sub32(result, left, right);
+ if (cc == eq) {
+ __ Seqz(result, result);
+ } else {
+ __ Snez(result, result);
+ }
+ return;
+ }
if (COMPRESS_POINTERS_BOOL && (instr->arch_opcode() == kRiscvCmp32)) {
Register temp0 = i.TempRegister(0);
Register temp1 = right.is_reg() ? i.TempRegister(1) : no_reg;
@@ -5464,8 +5517,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ RestoreVectorRegisters(simd128_regs_to_save);
__ MultiPopFPU(fp_regs_to_save);
__ MultiPop(regs_to_save);
@@ -5473,8 +5525,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ Call(static_cast<intptr_t>(Builtin::kWasmStackOverflow),
RelocInfo::WASM_STUB_CALL);
// We come from WebAssembly, there are no references for the GC.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
diff --git a/deps/v8/src/compiler/backend/riscv/instruction-codes-riscv.h b/deps/v8/src/compiler/backend/riscv/instruction-codes-riscv.h
index 45aa81fa043..d52cf83a6a7 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-codes-riscv.h
+++ b/deps/v8/src/compiler/backend/riscv/instruction-codes-riscv.h
@@ -50,6 +50,8 @@ namespace compiler {
TARGET_ARCH_OPCODE_WITH_MEMORY_ACCESS_MODE_LIST(V) \
V(RiscvAdd64) \
V(RiscvSub64) \
+ V(RiscvAddOvf32) \
+ V(RiscvSubOvf32) \
V(RiscvAdd128) \
V(RiscvSub128) \
V(RiscvMulHigh64) \
@@ -99,6 +101,7 @@ namespace compiler {
V(RiscvAtomicStoreCompressTagged) \
V(RiscvWord64AtomicCompareExchangeUint64) \
V(RiscvCmp32) \
+ V(RiscvCmp32Eq) \
V(RiscvCmpZero32) \
V(RiscvTst64)
#elif V8_TARGET_ARCH_RISCV32
diff --git a/deps/v8/src/compiler/backend/riscv/instruction-scheduler-riscv.cc b/deps/v8/src/compiler/backend/riscv/instruction-scheduler-riscv.cc
index b998c78245c..35c0037371d 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-scheduler-riscv.cc
+++ b/deps/v8/src/compiler/backend/riscv/instruction-scheduler-riscv.cc
@@ -20,6 +20,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvSubOvfWord:
#if V8_TARGET_ARCH_RISCV64
case kRiscvAdd32:
+ case kRiscvAddOvf32:
case kRiscvBitcastDL:
case kRiscvBitcastLD:
case kRiscvByteSwap64:
@@ -51,11 +52,13 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvFloat64RoundTruncate:
case kRiscvFloat64RoundUp:
case kRiscvSub32:
+ case kRiscvSubOvf32:
case kRiscvTruncLD:
case kRiscvTruncLS:
case kRiscvTruncUlD:
case kRiscvTruncUlS:
case kRiscvCmp32:
+ case kRiscvCmp32Eq:
case kRiscvCmpZero32:
#elif V8_TARGET_ARCH_RISCV32
case kRiscvAdd32:
@@ -1104,9 +1107,11 @@ int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
#if V8_TARGET_ARCH_RISCV64
case kRiscvAdd32:
case kRiscvAdd64:
+ case kRiscvAddOvf32:
return Add64Latency(instr->InputAt(1)->IsRegister());
case kRiscvSub32:
case kRiscvSub64:
+ case kRiscvSubOvf32:
return Sub64Latency(instr->InputAt(1)->IsRegister());
case kRiscvAdd128:
case kRiscvSub128:
@@ -1794,9 +1799,12 @@ ArchInstResource InstructionScheduler::GetInstructionResource(
case kRiscvCtzw:
case kRiscvCpopw:
case kRiscvCmp32:
+ case kRiscvCmp32Eq:
case kRiscvCmpZero32:
case kRiscvAdd32:
case kRiscvSub32:
+ case kRiscvAddOvf32:
+ case kRiscvSubOvf32:
case kRiscvAddOvfWord:
case kRiscvSubOvfWord:
case kRiscvEnableDebugTrace:
diff --git a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h
index fa77fe299e7..f8a310591e0 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h
+++ b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h
@@ -348,84 +348,84 @@ void InstructionSelector::VisitLoadTransform(OpIndex node) {
case Simd128LoadTransformOp::TransformKind::k8Splat:
opcode = kRiscvS128LoadSplat | EncodeElementWidth(E8);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k16Splat:
opcode = kRiscvS128LoadSplat | EncodeElementWidth(E16);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k32Splat:
opcode = kRiscvS128LoadSplat | EncodeElementWidth(E32);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k64Splat:
opcode = kRiscvS128LoadSplat | EncodeElementWidth(E64);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k8x8S:
opcode = kRiscvS128Load64ExtendS | EncodeElementWidth(E16);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k8x8U:
opcode = kRiscvS128Load64ExtendU | EncodeElementWidth(E16);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k16x4S:
opcode = kRiscvS128Load64ExtendS | EncodeElementWidth(E32);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k16x4U:
opcode = kRiscvS128Load64ExtendU | EncodeElementWidth(E32);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k32x2S:
opcode = kRiscvS128Load64ExtendS | EncodeElementWidth(E64);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k32x2U:
opcode = kRiscvS128Load64ExtendU | EncodeElementWidth(E64);
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k32Zero:
opcode = kRiscvS128Load32Zero;
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
case Simd128LoadTransformOp::TransformKind::k64Zero:
opcode = kRiscvS128Load64Zero;
if (is_trapping) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitS128Load(this, node, opcode);
break;
@@ -1181,7 +1181,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
uint32_t val[kUint32Immediates];
const turboshaft::Simd128ConstantOp& constant =
this->Get(node).template Cast<turboshaft::Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
diff --git a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv32.cc b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv32.cc
index 5da898cba36..9bf247bae43 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv32.cc
+++ b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv32.cc
@@ -154,7 +154,7 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
InstructionCode opcode = kRiscvS128StoreLane;
opcode |= EncodeElementWidth(ByteSizeToSew(store.lane_size()));
if (store.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
RiscvOperandGenerator g(this);
@@ -179,7 +179,7 @@ void InstructionSelector::VisitLoadLane(OpIndex node) {
InstructionCode opcode = kRiscvS128LoadLane;
opcode |= EncodeElementWidth(ByteSizeToSew(load.lane_size()));
if (load.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
RiscvOperandGenerator g(this);
@@ -284,8 +284,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
}
code |= RecordWriteModeField::encode(record_write_mode);
}
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
@@ -1039,13 +1039,14 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
inputs[input_count++] = g.UseUniqueRegister(new_value);
InstructionOperand outputs[1];
outputs[0] = g.UseUniqueRegister(node);
- InstructionOperand temp[3];
+ InstructionOperand temp[4];
temp[0] = g.TempRegister();
temp[1] = g.TempRegister();
temp[2] = g.TempRegister();
+ temp[3] = g.TempRegister();
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
- selector->Emit(code, 1, outputs, input_count, inputs, 3, temp);
+ selector->Emit(code, 1, outputs, input_count, inputs, 4, temp);
}
void InstructionSelector::VisitWord32AtomicExchange(OpIndex node) {
diff --git a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc
index a85d103593c..58213f1efab 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc
+++ b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc
@@ -29,6 +29,8 @@ bool RiscvOperandGenerator::CanBeImmediate(int64_t value,
case kRiscvShr64:
return is_uint6(value);
case kRiscvAdd32:
+ case kRiscvAddOvf32:
+ case kRiscvSubOvf32:
case kRiscvAnd32:
case kRiscvAnd:
case kRiscvAdd64:
@@ -38,6 +40,9 @@ bool RiscvOperandGenerator::CanBeImmediate(int64_t value,
case kRiscvTst32:
case kRiscvXor:
return is_int12(value);
+ case kRiscvCmp32:
+ case kRiscvCmp32Eq:
+ return is_int12(static_cast<int32_t>(value));
case kRiscvLb:
case kRiscvLbu:
case kRiscvSb:
@@ -520,7 +525,7 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
InstructionCode opcode = kRiscvS128StoreLane;
opcode |= EncodeElementWidth(ByteSizeToSew(store.lane_size()));
if (store.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
RiscvOperandGenerator g(this);
@@ -552,7 +557,7 @@ void InstructionSelector::VisitLoadLane(OpIndex node) {
InstructionCode opcode = kRiscvS128LoadLane;
opcode |= EncodeElementWidth(ByteSizeToSew(load.lane_size()));
if (load.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
RiscvOperandGenerator g(this);
@@ -704,13 +709,8 @@ void InstructionSelector::VisitLoad(OpIndex node) {
auto load = load_view(node);
InstructionCode opcode = kArchNop;
opcode = GetLoadOpcode(load.ts_loaded_rep(), load.ts_result_rep());
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- if (traps_on_null) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- }
+ if (load.is_trapping()) {
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
EmitLoad(this, node, opcode);
}
@@ -768,8 +768,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
code = kArchStoreWithWriteBarrier;
code |= RecordWriteModeField::encode(record_write_mode);
}
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
return;
@@ -792,10 +792,8 @@ void InstructionSelector::VisitStore(OpIndex node) {
return;
}
- if (store_view.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_view.access_kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (TryFoldStore(this, node, code, base, index, g.NoOutput(), value)) {
@@ -1112,7 +1110,8 @@ void VisitWideAddSub(InstructionSelector* selector, OpIndex node, bool is_add) {
InstructionOperand outputs[2];
size_t output_count = 0;
- inputs[input_count++] = g.UseRegister(op.left_low());
+ inputs[input_count++] = is_add ? g.UseUniqueRegister(op.left_low())
+ : g.UseRegister(op.left_low());
inputs[input_count++] = g.UseRegister(op.right_low());
inputs[input_count++] = g.UseUniqueRegister(op.left_high());
@@ -1135,6 +1134,10 @@ void InstructionSelector::VisitUint64Sub128(OpIndex node) {
VisitWideAddSub(this, node, false);
}
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNIMPLEMENTED();
+}
+
void InstructionSelector::VisitInt32MulHigh(OpIndex node) {
VisitRRR(this, kRiscvMulHigh32, node);
}
@@ -1570,40 +1573,35 @@ void InstructionSelector::VisitChangeUint32ToUint64(OpIndex node) {
Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
return;
}
- if (this->Get(value).opcode == Opcode::kChange) {
- const ChangeOp& change = this->Get(value).Cast<ChangeOp>();
- OpIndex change_input = change.input();
- // ToUint64(ToUint32(fp32)) wll drop Nan boxing
- // So riscv use kRiscvBitcastDL to change fp32 into Uint64, which can keep
- // Nan Box.See issues/469801435.
- if (change.Is<Opmask::kChangeFloat32ToUint32>()) {
- Emit(kRiscvBitcastDL, g.DefineAsRegister(node),
- g.UseRegister(change_input));
- return;
- }
- }
Emit(kRiscvZeroExtendWord, g.DefineAsRegister(node), g.UseRegister(value));
}
bool InstructionSelector::ZeroExtendsWord32ToWord64NoPhis(OpIndex node) {
DCHECK(!this->Get(node).Is<PhiOp>());
const Operation& op = this->Get(node);
- if (op.opcode == Opcode::kLoad) {
- auto load = this->load_view(node);
- LoadRepresentation load_rep = load.loaded_rep();
- if (load_rep.IsUnsigned()) {
- switch (load_rep.representation()) {
- case MachineRepresentation::kWord8:
- case MachineRepresentation::kWord16:
- case MachineRepresentation::kWord32:
- return true;
- default:
- return false;
+ switch (op.opcode) {
+ case Opcode::kProjection:
+ return ZeroExtendsWord32ToWord64NoPhis(op.Cast<ProjectionOp>().input());
+ case Opcode::kLoad: {
+ auto load = this->load_view(node);
+ LoadRepresentation load_rep = load.loaded_rep();
+ if (load_rep.IsUnsigned()) {
+ switch (load_rep.representation()) {
+ case MachineRepresentation::kWord8:
+ case MachineRepresentation::kWord16:
+ return true;
+ case MachineRepresentation::kWord32:
+ return !load.is_atomic();
+ default:
+ return false;
+ }
}
+ return false;
}
+ default:
+ // All other 32-bit operations sign-extend to the upper 32 bits
+ return false;
}
- // All other 32-bit operations sign-extend to the upper 32 bits
- return false;
}
void InstructionSelector::VisitTruncateInt64ToInt32(OpIndex node) {
@@ -1808,6 +1806,30 @@ void VisitFullWord32Compare(InstructionSelector* selector, OpIndex node,
void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
FlagsContinuation* cont) {
+ RiscvOperandGenerator g(selector);
+ const Operation& op = selector->Get(node);
+ DCHECK_EQ(op.input_count, 2);
+ // For equality/inequality only the low 32 bits matter. Compute the 32-bit
+ // difference with Sub32 (which sign-extends its result) and compare against
+ // zero. This avoids the two Shl64 normalization instructions emitted by
+ // VisitFullWord32Compare. The reasoning holds regardless of the (possibly
+ // dirty) upper 32 bits of the operands.
+ if (!cont->IsNone() &&
+ (cont->condition() == kEqual || cont->condition() == kNotEqual)) {
+ OpIndex left = op.input(0);
+ OpIndex right = op.input(1);
+ // Make sure an immediate, if any, ends up on the right.
+ if (!g.CanBeImmediate(right, kRiscvCmp32Eq) &&
+ g.CanBeImmediate(left, kRiscvCmp32Eq)) {
+ cont->Commute();
+ std::swap(left, right);
+ }
+ Instruction* instr =
+ VisitCompare(selector, kRiscvCmp32Eq, g.UseRegister(left),
+ g.UseOperand(right, kRiscvCmp32Eq), cont);
+ selector->UpdateSourcePosition(instr, node);
+ return;
+ }
VisitFullWord32Compare(selector, node, kRiscvCmp, cont);
}
@@ -1872,11 +1894,8 @@ void VisitAtomicLoad(InstructionSelector* selector, OpIndex node,
UNREACHABLE();
}
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- code |= AccessModeField::encode(traps_on_null
- ? kMemoryAccessTrappingNullDereference
- : kMemoryAccessTrappingMemOutOfBounds);
+ if (load.is_trapping()) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (g.CanBeImmediate(index, code)) {
@@ -1957,10 +1976,8 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
code |= RecordWriteModeField::encode(record_write_mode);
}
- if (store.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_params.kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_params.kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
code |= AddressingModeField::encode(addressing_mode);
@@ -1997,10 +2014,8 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
}
code |= AtomicWidthField::encode(width);
- if (store.is_store_trap_on_null()) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else if (store_params.kind() == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ if (store_params.kind() == MemoryAccessKind::kTrapping) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
if (g.CanBeImmediate(index, code)) {
selector->Emit(code | AddressingModeField::encode(kMode_MRI) |
@@ -2052,7 +2067,7 @@ void VisitAtomicBinop(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, 1, outputs, input_count, inputs, 4, temps);
}
@@ -2185,35 +2200,15 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
TryCast<OverflowCheckedBinopOp>(node);
binop && CanDoBranchIfOverflowFusion(node)) {
const bool is64 = binop->rep == WordRepresentation::Word64();
- OpIndex right_node = binop->input(1);
- RiscvOperandGenerator g(this);
- // Check if the right-hand side operand can be encoded as an immediate
- // value for a 32-bit operand add/sub. This is used to
- // determine whether we can utilize the more efficient overflow
- // checking path specifically designed for 32-bit operations with
- // immediate operands.
- const bool use_32 = g.CanBeImmediate(right_node, kRiscvAdd32);
switch (binop->kind) {
case OverflowCheckedBinopOp::Kind::kSignedAdd: {
cont->OverwriteAndNegateIfEqual(kOverflow);
- ArchOpcode opcode = kRiscvAddOvfWord;
- if (!is64) {
- if (use_32)
- opcode = kRiscvAdd32;
- else
- opcode = kRiscvAdd64;
- }
+ ArchOpcode opcode = is64 ? kRiscvAddOvfWord : kRiscvAddOvf32;
return VisitBinop<Int32BinopMatcher>(this, node, opcode, cont);
}
case OverflowCheckedBinopOp::Kind::kSignedSub: {
cont->OverwriteAndNegateIfEqual(kOverflow);
- ArchOpcode opcode = kRiscvSubOvfWord;
- if (!is64) {
- if (use_32)
- opcode = kRiscvSub32;
- else
- opcode = kRiscvSub64;
- }
+ ArchOpcode opcode = is64 ? kRiscvSubOvfWord : kRiscvSubOvf32;
return VisitBinop<Int32BinopMatcher>(this, node, opcode, cont);
}
case OverflowCheckedBinopOp::Kind::kSignedMul:
@@ -2235,7 +2230,12 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
// Matching IR:
// 7: Word64And
// 8: Word64Equal(#7)
- VisitWordCompare(this, value, kRiscvTst64, cont, true);
+ // For Word32And the operands may have dirty bits in the upper 32 bits
+ // (e.g. from Word32Xor with -1, which lowers to a 64-bit xori), so the
+ // zero test must normalize the 32-bit result before branching.
+ bool is_32 = value_op.Is<Opmask::kWord32BitwiseAnd>();
+ VisitWordCompare(this, value, is_32 ? kRiscvTst32 : kRiscvTst64, cont,
+ true);
return;
}
}
@@ -2243,27 +2243,25 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
// Continuation could not be combined with a compare, emit compare against
// 0.
const ComparisonOp* comparison = this->Get(user).TryCast<ComparisonOp>();
-#ifdef V8_COMPRESS_POINTERS
- if ((comparison &&
- comparison->rep.value() == RegisterRepresentation::Word64()) ||
- value_op.Is<Opmask::kWord32BitwiseAnd>() ||
- value_op.Is<Opmask::kTruncateWord64ToWord32>() ||
+ // 32-bit ALU results are not guaranteed to have their upper 32 bits
+ // correctly extended on riscv64 (e.g. Word32Xor with -1 lowers to a
+ // full-width xori), so a Word32 value must use a zero test that normalizes
+ // the upper bits before branching. Note that a null |comparison| means the
+ // branch condition is a Word32 value directly (BranchOp::condition() is
+ // always Word32). Values that are known to be properly extended can use the
+ // cheaper full-width test.
+ bool is_64_bit =
+ comparison &&
+ (comparison->rep.value() == RegisterRepresentation::Word64() ||
+ (!COMPRESS_POINTERS_BOOL &&
+ comparison->rep.value() != RegisterRepresentation::Word32()));
+ if (is_64_bit || value_op.Is<Opmask::kTruncateWord64ToWord32>() ||
IsLoadWord32OrSmaller(this, value) ||
IsSignExtendWord32ToWord64(value_op)) {
- // If the value_op is sign-extended or lw/lhu/lh/lbu/lb, we can use
- // EmitWordCompareZero to emit a 32-bit compare zero.
return EmitWordCompareZero(this, value, cont);
} else {
return EmitWord32CompareZero(this, value, cont);
}
-#else
- if (comparison &&
- comparison->rep.value() == RegisterRepresentation::Word32()) {
- return EmitWord32CompareZero(this, value, cont);
- } else {
- return EmitWordCompareZero(this, value, cont);
- }
-#endif
}
void InstructionSelector::VisitWord32Equal(OpIndex node) {
@@ -2292,8 +2290,8 @@ void InstructionSelector::VisitWord32Equal(OpIndex node) {
if (RootsTable::IsReadOnly(root_index)) {
Tagged_t ptr =
MacroAssemblerBase::ReadOnlyRootPtr(root_index, isolate());
- if (g.CanBeImmediate(ptr, kRiscvCmp32)) {
- VisitCompare(this, kRiscvCmp32, g.UseRegister(left),
+ if (g.CanBeImmediate(ptr, kRiscvCmp32Eq)) {
+ VisitCompare(this, kRiscvCmp32Eq, g.UseRegister(left),
g.TempImmediate(static_cast<int32_t>(ptr)), &cont);
return;
}
@@ -2329,19 +2327,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(OpIndex node) {
OptionalOpIndex ovf = FindProjection(node, 1);
if (ovf.valid() && IsUsed(ovf.value())) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf.value());
- const Operation& binop = Get(node);
- OpIndex right_node = binop.input(1);
- RiscvOperandGenerator g(this);
- // Check if the right-hand side operand can be encoded as an immediate
- // value for a 32-bit operand add/sub. This is used to
- // determine whether we can utilize the more efficient overflow
- // checking path specifically designed for 32-bit operations with
- // immediate operands.
- // TODO(yahan): Implement the 32-bit overflow fast check with Constant which
- // don't be encoded into instructions.
- const bool use_32 = g.CanBeImmediate(right_node, kRiscvAdd32);
- return VisitBinop<Int32BinopMatcher>(
- this, node, use_32 ? kRiscvAdd32 : kRiscvAdd64, &cont);
+ return VisitBinop<Int32BinopMatcher>(this, node, kRiscvAddOvf32, &cont);
}
FlagsContinuation cont;
VisitBinop<Int32BinopMatcher>(this, node, kRiscvAdd64, &cont);
@@ -2351,12 +2337,7 @@ void InstructionSelector::VisitInt32SubWithOverflow(OpIndex node) {
OptionalOpIndex ovf = FindProjection(node, 1);
if (ovf.valid() && IsUsed(ovf.value())) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf.value());
- const Operation& binop = Get(node);
- OpIndex right_node = binop.input(1);
- RiscvOperandGenerator g(this);
- const bool use_32 = g.CanBeImmediate(right_node, kRiscvSub32);
- return VisitBinop<Int32BinopMatcher>(
- this, node, use_32 ? kRiscvSub32 : kRiscvSub64, &cont);
+ return VisitBinop<Int32BinopMatcher>(this, node, kRiscvSubOvf32, &cont);
}
FlagsContinuation cont;
VisitBinop<Int32BinopMatcher>(this, node, kRiscvSub64, &cont);
@@ -2482,7 +2463,7 @@ void VisitAtomicExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, 1, outputs, input_count, inputs, 3, temp);
}
@@ -2518,12 +2499,12 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
InstructionOperand outputs[] = {g.UseUniqueRegister(node)};
InstructionOperand temps[] = {g.TempRegister(), g.TempRegister(),
- g.TempRegister()};
+ g.TempRegister(), g.TempRegister()};
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, input_count, inputs,
arraysize(temps), temps);
diff --git a/deps/v8/src/compiler/backend/riscv/register-constraints-riscv.h b/deps/v8/src/compiler/backend/riscv/register-constraints-riscv.h
index e85979c30ce..bfaf3ff8236 100644
--- a/deps/v8/src/compiler/backend/riscv/register-constraints-riscv.h
+++ b/deps/v8/src/compiler/backend/riscv/register-constraints-riscv.h
@@ -30,12 +30,12 @@ enum class RiscvRegisterConstraint {
};
using RiscvRegisterConstraintField =
- VectorLengthField::Next<RiscvRegisterConstraint, 3>;
+ AccessModeField::Next<RiscvRegisterConstraint, 3>;
static_assert(MiscField::kSize == 9);
static_assert(LaneSizeField::kSize == 2);
static_assert(VectorLengthField::kSize == 2);
-static_assert(AccessModeField::kSize == 2);
+static_assert(AccessModeField::kSize == 1);
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc
index cf5c840dca3..d9798f6f565 100644
--- a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc
+++ b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc
@@ -305,8 +305,7 @@ class OutOfLineTrap final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) {
__ stop();
}
@@ -3620,8 +3619,7 @@ void CodeGenerator::AssembleConstructFrame() {
// return in this case.
// So either way, we can just ignore any references and record an empty
// safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ MultiPopF64OrV128(fp_regs_to_save, r1);
__ MultiPop(regs_to_save);
} else {
@@ -3629,8 +3627,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
if (v8_flags.debug_code) __ stop();
}
diff --git a/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc b/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc
index c922d6c5610..70b7c171bb9 100644
--- a/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc
+++ b/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc
@@ -3135,7 +3135,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
uint32_t val[kSimd128Size / sizeof(uint32_t)];
const Simd128ConstantOp& constant =
this->Get(node).template Cast<Simd128ConstantOp>();
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros, avoid emitting code for generic constants.
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
diff --git a/deps/v8/src/compiler/backend/x64/code-generator-x64.cc b/deps/v8/src/compiler/backend/x64/code-generator-x64.cc
index b0be9bc5878..42ae89aeba4 100644
--- a/deps/v8/src/compiler/backend/x64/code-generator-x64.cc
+++ b/deps/v8/src/compiler/backend/x64/code-generator-x64.cc
@@ -675,8 +675,7 @@ class WasmOutOfLineTrap : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ near_call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
- ReferenceMap* reference_map = gen_->zone()->New<ReferenceMap>(gen_->zone());
- gen_->RecordSafepoint(reference_map);
+ gen_->RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
@@ -687,8 +686,7 @@ void RecordTrapInfoIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
int pc) {
const MemoryAccessMode access_mode = instr->memory_access_mode();
- if (access_mode == kMemoryAccessTrappingMemOutOfBounds ||
- access_mode == kMemoryAccessTrappingNullDereference) {
+ if (access_mode == kMemoryAccessTrapping) {
codegen->RecordTrappingInstruction(pc);
}
}
@@ -2084,10 +2082,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchAtomicStoreWithWriteBarrier: {
// {EmitTSANAwareStore} calls RecordTrapInfoIfNeeded. No need to do it
// here.
- RecordWriteMode mode =
- arch_opcode == kArchStoreWithWriteBarrier
- ? RecordWriteModeField::decode(instr->opcode())
- : AtomicStoreRecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
Register object = i.InputRegister(0);
@@ -2311,26 +2306,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Register carry_in = i.InputRegister(last_input_index);
Register out_low = i.OutputRegister(0);
Register out_high = no_reg;
- Register temp = no_reg;
bool use_out_high = instr->OutputCount() > 1;
- bool use_temp = false;
if (use_out_high) {
out_high = i.OutputRegister(1);
- temp = i.TempRegister(0);
- size_t end = instr->InputCount();
- for (size_t j = 0; j < end; j++) {
+ DCHECK_NE(out_high, out_low);
+ for (size_t j = 0; j < instr->InputCount(); ++j) {
if (HasRegisterInput(instr, j)) {
- CHECK_NE(i.InputRegister(j), temp);
- if (i.InputRegister(j) == out_high) {
- use_temp = true;
- out_high = temp;
- }
+ DCHECK_NE(i.InputRegister(j), out_high);
}
}
+ // GCC style: just addc, no setcc.
+ __ xorq(out_high, out_high);
}
- // GCC style: just addc, no setcc.
- if (use_out_high) __ xorq(out_high, out_high);
size_t index = 1;
if (HasAddressingMode(instr)) {
Operand b = i.MemoryOperand(&index);
@@ -2342,7 +2330,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (use_out_high) __ adcq(out_high, Immediate(0));
__ addq(out_low, carry_in);
if (use_out_high) __ adcq(out_high, Immediate(0));
- if (use_temp) __ movq(i.OutputRegister(1), temp);
break;
}
@@ -3582,10 +3569,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kX64Movsh:
if (instr->HasOutput()) {
CpuFeatureScope f16c_scope(masm(), F16C);
- CpuFeatureScope avx2_scope(masm(), AVX2);
- RecordTrapInfoIfNeeded(zone(), this, opcode, instr, __ pc_offset());
- __ vpbroadcastw(i.OutputDoubleRegister(), i.MemoryOperand());
- __ vcvtph2ps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+ XMMRegister dst = i.OutputDoubleRegister();
+ if (CpuFeatures::IsSupported(AVX2)) {
+ CpuFeatureScope avx2_scope(masm(), AVX2);
+ RecordTrapInfoIfNeeded(zone(), this, opcode, instr, __ pc_offset());
+ __ vpbroadcastw(dst, i.MemoryOperand());
+ } else {
+ CpuFeatureScope avx_scope(masm(), AVX);
+ __ vxorps(dst, dst, dst);
+ RecordTrapInfoIfNeeded(zone(), this, opcode, instr, __ pc_offset());
+ __ vpinsrw(dst, dst, i.MemoryOperand(), 0);
+ }
+ __ vcvtph2ps(dst, dst);
} else {
CpuFeatureScope f16c_scope(masm(), F16C);
size_t index = 0;
@@ -8375,10 +8370,20 @@ void CodeGenerator::FinishFrame(Frame* frame) {
if (!saves.is_empty()) { // Save callee-saved registers.
frame->AllocateSavedCalleeRegisterSlots(saves.Count());
}
+ if (v8_flags.enforce_x64_16byte_alignment) {
+ frame->AlignFrame(2 * kSystemPointerSize);
+ }
}
void CodeGenerator::AssembleConstructFrame() {
auto call_descriptor = linkage()->GetIncomingDescriptor();
+
+ if (v8_flags.enforce_x64_16byte_alignment) {
+ // The frame has been previously padded in CodeGenerator::FinishFrame().
+ DCHECK_EQ(frame()->GetTotalFrameSlotCount() % 2, 0);
+ DCHECK_EQ(frame()->GetReturnSlotCount() % 2, 0);
+ }
+
if (frame_access_state()->has_frame()) {
int pc_base = __ pc_offset();
@@ -8492,8 +8497,7 @@ void CodeGenerator::AssembleConstructFrame() {
// allocating the stack overflow exception object, but the call did not
// return in this case.
// So either way, we can just record an empty safepoint here.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ PopAll(fp_regs_to_save);
__ PopAll(regs_to_save);
} else {
@@ -8501,8 +8505,7 @@ void CodeGenerator::AssembleConstructFrame() {
RelocInfo::WASM_STUB_CALL);
// The call does not return, hence we can ignore any references and just
// define an empty safepoint.
- ReferenceMap* reference_map = zone()->New<ReferenceMap>(zone());
- RecordSafepoint(reference_map);
+ RecordSafepointWithoutTaggedSlots();
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
__ bind(&done);
diff --git a/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc b/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc
index af76d6991e4..e13d8b99d85 100644
--- a/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc
+++ b/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc
@@ -1162,7 +1162,7 @@ void InstructionSelector::VisitLoadLane(OpIndex node) {
// x64 supports unaligned loads.
DCHECK(!load.kind.maybe_unaligned);
if (load.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
Emit(opcode, 1, outputs, input_count, inputs);
}
@@ -1214,7 +1214,7 @@ void InstructionSelector::VisitLoadTransform(OpIndex node) {
DCHECK(!op.load_kind.maybe_unaligned);
InstructionCode code = opcode;
if (op.load_kind.with_trap_handler) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
VisitLoad(node, node, code);
}
@@ -1225,7 +1225,7 @@ void InstructionSelector::VisitS256Const(OpIndex node) {
static const int kUint32Immediates = kSimd256Size / sizeof(uint32_t);
uint32_t val[kUint32Immediates];
const Simd256ConstantOp& constant = Cast<Simd256ConstantOp>(node);
- memcpy(val, constant.value, kSimd256Size);
+ memcpy(val, constant.value.data(), kSimd256Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = std::all_of(std::begin(val), std::end(val),
[](uint32_t v) { return v == 0; });
@@ -1297,7 +1297,7 @@ void InstructionSelector::VisitSimd256LoadTransform(OpIndex node) {
DCHECK(!op.load_kind.maybe_unaligned);
InstructionCode code = opcode;
if (op.load_kind.with_trap_handler) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
VisitLoad(node, node, code);
}
@@ -1407,13 +1407,8 @@ void InstructionSelector::VisitLoad(OpIndex node, OpIndex value,
InstructionCode code = opcode | AddressingModeField::encode(mode);
if (this->is_load(node)) {
auto load = load_view(node);
- bool traps_on_null;
- if (load.is_trapping(&traps_on_null)) {
- if (traps_on_null) {
- code |= AccessModeField::encode(kMemoryAccessTrappingNullDereference);
- } else {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- }
+ if (load.is_trapping()) {
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
}
Emit(code, 1, outputs, input_count, inputs, temp_count, temps);
@@ -1450,7 +1445,7 @@ void VisitAtomicExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs,
temps.size(), temps.data());
@@ -1479,23 +1474,17 @@ void VisitStoreCommon(InstructionSelector* selector,
write_barrier_kind = kFullWriteBarrier;
}
- const auto access_mode =
- acs_kind == MemoryAccessKind::kTrapping
- ? (store.is_store_trap_on_null()
- ? kMemoryAccessTrappingNullDereference
- : MemoryAccessMode::kMemoryAccessTrappingMemOutOfBounds)
- : MemoryAccessMode::kMemoryAccessDirect;
+ const auto access_mode = acs_kind == MemoryAccessKind::kTrapping
+ ? MemoryAccessMode::kMemoryAccessTrapping
+ : MemoryAccessMode::kMemoryAccessDirect;
DCHECK_IMPLIES(write_barrier_kind == kSkippedWriteBarrier,
v8_flags.verify_write_barriers);
if (write_barrier_kind != kNoWriteBarrier &&
!v8_flags.disable_write_barriers) {
-#if DEBUG
- MachineRepresentation mach_rep = store_rep.representation();
- DCHECK(CanBeTaggedOrCompressedOrIndirectPointer(mach_rep) ||
- CanBeTaggedSigned(mach_rep));
-#endif // DEBUG
+ DCHECK(
+ CanBeTaggedOrCompressedOrIndirectPointer(store_rep.representation()));
// Uncompressed stores should not happen if we need a write barrier.
CHECK((store.ts_stored_rep() !=
MemoryRepresentation::AnyUncompressedTagged()) &&
@@ -1533,9 +1522,7 @@ void VisitStoreCommon(InstructionSelector* selector,
: kArchStoreWithWriteBarrier;
const RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
- code |= is_atomic
- ? AtomicStoreRecordWriteModeField::encode(record_write_mode)
- : RecordWriteModeField::encode(record_write_mode);
+ code |= RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
code |= AccessModeField::encode(access_mode);
@@ -1657,7 +1644,7 @@ void InstructionSelector::VisitStoreLane(OpIndex node) {
opcode |= AddressingModeField::encode(addressing_mode);
if (store.kind.with_trap_handler) {
- opcode |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ opcode |= AccessModeField::encode(kMemoryAccessTrapping);
}
InstructionOperand value_operand = g.UseRegister(store.value());
@@ -2561,7 +2548,9 @@ void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
inputs[input_count++] = g.UseRegister(op.first());
auto b = op.second();
int effect_level = this->GetEffectLevel(node);
- if (g.CanBeMemoryOperand(opcode, node, b, effect_level)) {
+ if (g.CanBeImmediate(b)) {
+ inputs[input_count++] = g.UseImmediate(b);
+ } else if (g.CanBeMemoryOperand(opcode, node, b, effect_level)) {
AddressingMode addressing_mode = g.GetEffectiveAddressMemoryOperand(
b, inputs, &input_count,
X64OperandGenerator::RegisterUseKind::kUseUniqueRegister);
@@ -2577,14 +2566,11 @@ void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
g.DefineSameAsFirst(out_low.valid() ? out_low.value() : node);
OptionalOpIndex out_high = FindProjection(node, 1);
- InstructionOperand temps[1];
- size_t temp_count = 0;
if (out_high.valid() && IsUsed(out_high.value())) {
outputs[output_count++] = g.DefineAsRegister(out_high.value());
- temps[temp_count++] = g.TempRegister();
}
- Emit(opcode, output_count, outputs, input_count, inputs, temp_count, temps);
+ Emit(opcode, output_count, outputs, input_count, inputs);
}
void InstructionSelector::VisitInt32Div(OpIndex node) {
@@ -2980,10 +2966,8 @@ void VisitFloatBinop(InstructionSelector* selector, OpIndex node,
// no other uses. Therefore, we can record the fact that 'right' was
// embedded in 'node' and we can later delete the Load instruction.
selector->MarkAsTrappingInstruction(node);
- avx_opcode |=
- AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
- sse_opcode |=
- AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ avx_opcode |= AccessModeField::encode(kMemoryAccessTrapping);
+ sse_opcode |= AccessModeField::encode(kMemoryAccessTrapping);
selector->SetTrappingLoadToRemove(right);
trapping_load = right;
}
@@ -3992,7 +3976,7 @@ void VisitAtomicBinop(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs,
arraysize(temps), temps);
@@ -4020,7 +4004,7 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
AtomicWidthField::encode(width);
if (access_kind == MemoryAccessKind::kTrapping) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
selector->Emit(code, arraysize(outputs), outputs, arraysize(inputs), inputs,
temps.size(), temps.data());
@@ -4943,7 +4927,7 @@ void InstructionSelector::VisitS128Const(OpIndex node) {
static const int kUint32Immediates = kSimd128Size / sizeof(uint32_t);
uint32_t val[kUint32Immediates];
const Simd128ConstantOp& constant = Cast<Simd128ConstantOp>(node);
- memcpy(val, constant.value, kSimd128Size);
+ memcpy(val, constant.value.data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
@@ -5320,7 +5304,7 @@ static bool MatchSimd128Constant(InstructionSelector* selector, OpIndex node,
DCHECK_NOT_NULL(constant);
const Operation& op = selector->Get(node);
if (auto c = op.TryCast<Simd128ConstantOp>()) {
- std::memcpy(constant, c->value, kSimd128Size);
+ *constant = c->value;
return true;
}
return false;
@@ -6357,7 +6341,7 @@ void InstructionSelector::VisitF64x2PromoteLowF32x4(OpIndex node) {
const Simd128LoadTransformOp& load_transform =
Cast<Simd128LoadTransformOp>(input);
if (load_transform.load_kind.with_trap_handler) {
- code |= AccessModeField::encode(kMemoryAccessTrappingMemOutOfBounds);
+ code |= AccessModeField::encode(kMemoryAccessTrapping);
}
// LoadTransforms cannot be eliminated, so they are visited even if
// unused. Mark it as defined so that we don't visit it.
diff --git a/deps/v8/src/compiler/bytecode-graph-builder.cc b/deps/v8/src/compiler/bytecode-graph-builder.cc
index a2c973d6647..bdc98b4d3e8 100644
--- a/deps/v8/src/compiler/bytecode-graph-builder.cc
+++ b/deps/v8/src/compiler/bytecode-graph-builder.cc
@@ -241,6 +241,8 @@ class BytecodeGraphBuilder {
kSet,
// Define value to the receiver without checking the prototype chain.
kDefineOwn,
+ // Like kDefineOwn, but inside an object literal
+ kDefineOwnInLiteral
};
void BuildNamedStore(NamedStoreMode store_mode);
void BuildLdaLookupSlot(TypeofMode typeof_mode);
@@ -1570,6 +1572,11 @@ void BytecodeGraphBuilder::VisitLdaTheHole() {
environment()->BindAccumulator(node);
}
+void BytecodeGraphBuilder::VisitLdaTdzHole() {
+ Node* node = jsgraph()->TdzHoleConstant();
+ environment()->BindAccumulator(node);
+}
+
void BytecodeGraphBuilder::VisitLdaTrue() {
Node* node = jsgraph()->TrueConstant();
environment()->BindAccumulator(node);
@@ -2189,7 +2196,12 @@ void BytecodeGraphBuilder::BuildNamedStore(NamedStoreMode store_mode) {
DCHECK_EQ(FeedbackSlotKind::kDefineNamedOwn,
broker()->GetFeedbackSlotKind(feedback));
- op = javascript()->DefineNamedOwnProperty(name, feedback);
+ op = javascript()->DefineNamedOwnProperty(false, name, feedback);
+ } else if (store_mode == NamedStoreMode::kDefineOwnInLiteral) {
+ DCHECK_EQ(FeedbackSlotKind::kDefineNamedOwn,
+ broker()->GetFeedbackSlotKind(feedback));
+
+ op = javascript()->DefineNamedOwnProperty(true, name, feedback);
} else {
DCHECK_EQ(NamedStoreMode::kSet, store_mode);
LanguageMode language_mode =
@@ -2311,6 +2323,10 @@ void BytecodeGraphBuilder::VisitDefineNamedOwnProperty() {
BuildNamedStore(NamedStoreMode::kDefineOwn);
}
+void BytecodeGraphBuilder::VisitDefineNamedOwnPropertyInLiteral() {
+ BuildNamedStore(NamedStoreMode::kDefineOwnInLiteral);
+}
+
void BytecodeGraphBuilder::VisitSetKeyedProperty() {
PrepareEagerCheckpoint();
Node* value = environment()->LookupAccumulator();
@@ -3071,27 +3087,27 @@ void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
environment()->BindAccumulator(accumulator);
}
-void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
+void BytecodeGraphBuilder::VisitThrowReferenceErrorIfTdzHole() {
Node* accumulator = environment()->LookupAccumulator();
Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
- jsgraph()->TheHoleConstant());
+ jsgraph()->TdzHoleConstant());
Node* name =
jsgraph()->ConstantNoHole(MakeRefForConstantPoolOperand(0), broker());
BuildHoleCheckAndThrow(check_for_hole,
Runtime::kThrowAccessedUninitializedVariable, name);
}
-void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
+void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfTdzHole() {
Node* accumulator = environment()->LookupAccumulator();
Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
- jsgraph()->TheHoleConstant());
+ jsgraph()->TdzHoleConstant());
BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
}
-void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
+void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotTdzHole() {
Node* accumulator = environment()->LookupAccumulator();
Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
- jsgraph()->TheHoleConstant());
+ jsgraph()->TdzHoleConstant());
Node* check_for_not_hole =
NewNode(simplified()->BooleanNot(), check_for_hole);
BuildHoleCheckAndThrow(check_for_not_hole,
diff --git a/deps/v8/src/compiler/common-operator.cc b/deps/v8/src/compiler/common-operator.cc
index b739359b99f..37ab33d7f74 100644
--- a/deps/v8/src/compiler/common-operator.cc
+++ b/deps/v8/src/compiler/common-operator.cc
@@ -136,8 +136,8 @@ bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
}
size_t hash_value(DeoptimizeParameters p) {
- FeedbackSource::Hash feebdack_hash;
- return base::hash_combine(p.reason(), feebdack_hash(p.feedback()));
+ FeedbackSource::Hash feedback_hash;
+ return base::hash_combine(p.reason(), feedback_hash(p.feedback()));
}
std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
diff --git a/deps/v8/src/compiler/common-operator.h b/deps/v8/src/compiler/common-operator.h
index 1bc85b111e6..6499e23637c 100644
--- a/deps/v8/src/compiler/common-operator.h
+++ b/deps/v8/src/compiler/common-operator.h
@@ -148,12 +148,13 @@ class DeoptimizeParameters final {
FeedbackSource const feedback_;
};
-bool operator==(DeoptimizeParameters, DeoptimizeParameters);
-bool operator!=(DeoptimizeParameters, DeoptimizeParameters);
+V8_EXPORT_PRIVATE bool operator==(DeoptimizeParameters, DeoptimizeParameters);
+V8_EXPORT_PRIVATE bool operator!=(DeoptimizeParameters, DeoptimizeParameters);
-size_t hast_value(DeoptimizeParameters p);
+V8_EXPORT_PRIVATE size_t hash_value(DeoptimizeParameters p);
-std::ostream& operator<<(std::ostream&, DeoptimizeParameters p);
+V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
+ DeoptimizeParameters p);
DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const)
V8_WARN_UNUSED_RESULT;
diff --git a/deps/v8/src/compiler/fast-api-calls.cc b/deps/v8/src/compiler/fast-api-calls.cc
index ab54f345949..1772e5cb5f5 100644
--- a/deps/v8/src/compiler/fast-api-calls.cc
+++ b/deps/v8/src/compiler/fast-api-calls.cc
@@ -302,11 +302,12 @@ Node* FastApiCallBuilder::Build(FastApiCallFunction c_function,
Node* data_argument_to_pass = __ AdaptLocalArgument(data_argument);
+ START_ALLOW_USE_DEPRECATED()
+ constexpr int data_offset = offsetof(v8::FastApiCallbackOptions, data);
+ END_ALLOW_USE_DEPRECATED()
__ Store(StoreRepresentation(MachineType::PointerRepresentation(),
kNoWriteBarrier),
- stack_slot,
- static_cast<int>(offsetof(v8::FastApiCallbackOptions, data)),
- data_argument_to_pass);
+ stack_slot, data_offset, data_argument_to_pass);
initialize_options_(stack_slot);
diff --git a/deps/v8/src/compiler/frame-states.cc b/deps/v8/src/compiler/frame-states.cc
index 617627f0048..c6a123e895a 100644
--- a/deps/v8/src/compiler/frame-states.cc
+++ b/deps/v8/src/compiler/frame-states.cc
@@ -86,7 +86,8 @@ bool operator==(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
lhs.state_combine() == rhs.state_combine() &&
- *lhs.function_info() == *rhs.function_info();
+ (lhs.function_info() == rhs.function_info() ||
+ *lhs.function_info() == *rhs.function_info());
}
bool operator!=(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
diff --git a/deps/v8/src/compiler/frame-states.h b/deps/v8/src/compiler/frame-states.h
index e17798a1a8e..5eb50c6b5bf 100644
--- a/deps/v8/src/compiler/frame-states.h
+++ b/deps/v8/src/compiler/frame-states.h
@@ -185,21 +185,18 @@ class FrameStateInfo final {
const FrameStateFunctionInfo* info)
: bailout_id_(bailout_id),
frame_state_combine_(state_combine),
- info_(info) {}
-
- FrameStateType type() const {
- return info_ == nullptr ? FrameStateType::kUnoptimizedFunction
- : info_->type();
+ info_(info) {
+ DCHECK_NOT_NULL(info);
}
+
+ FrameStateType type() const { return info_->type(); }
BytecodeOffset bailout_id() const { return bailout_id_; }
OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
MaybeIndirectHandle<SharedFunctionInfo> shared_info() const {
- return info_ == nullptr ? MaybeIndirectHandle<SharedFunctionInfo>()
- : info_->shared_info();
+ return info_->shared_info();
}
MaybeIndirectHandle<BytecodeArray> bytecode_array() const {
- return info_ == nullptr ? MaybeIndirectHandle<BytecodeArray>()
- : info_->bytecode_array();
+ return info_->bytecode_array();
}
uint16_t parameter_count() const {
DCHECK_NOT_NULL(info_);
@@ -231,9 +228,10 @@ class FrameStateInfo final {
V8_EXPORT_PRIVATE bool operator==(FrameStateInfo const&, FrameStateInfo const&);
V8_EXPORT_PRIVATE bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
-size_t hash_value(FrameStateInfo const&);
+V8_EXPORT_PRIVATE size_t hash_value(FrameStateInfo const&);
-std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
+V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
+ FrameStateInfo const&);
enum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH };
diff --git a/deps/v8/src/compiler/heap-refs.cc b/deps/v8/src/compiler/heap-refs.cc
index 627f0824144..e6c1a18c71a 100644
--- a/deps/v8/src/compiler/heap-refs.cc
+++ b/deps/v8/src/compiler/heap-refs.cc
@@ -9,6 +9,7 @@
#include "src/base/logging.h"
#include "src/base/sanitizer/tsan.h"
#include "src/common/globals.h"
+#include "src/common/scoped-modification.h"
#include "src/compiler/js-heap-broker.h"
#include "src/objects/elements-kind.h"
#include "src/objects/heap-object.h"
@@ -507,7 +508,7 @@ class JSFunctionData : public JSObjectData {
InstanceType instance_type, IndirectHandle<JSFunction> object,
ObjectDataKind kind)
: JSObjectData(broker, storage, instance_type, object, kind) {
- Cache(broker);
+ broker->AddToJSFunctionCacheWorklist(this);
}
bool IsConsistentWithHeapState(JSHeapBroker* broker) const;
@@ -572,8 +573,14 @@ class JSFunctionData : public JSObjectData {
void set_used_field(UsedField used_field) { used_fields_ |= used_field; }
private:
+ friend class JSHeapBroker;
+
void Cache(JSHeapBroker* broker);
+ // Only used while this data is queued for caching, see
+ // JSHeapBroker::DrainJSFunctionCacheWorklist.
+ JSFunctionData* next_in_cache_worklist_ = nullptr;
+
#ifdef DEBUG
bool serialized_ = false;
#endif // DEBUG
@@ -711,6 +718,11 @@ int InstanceSizeWithMinSlack(JSHeapBroker* broker, MapRef map) {
} // namespace
// IMPORTANT: Keep this sync'd with JSFunctionData::IsConsistentWithHeapState.
+// IMPORTANT: This runs deferred (see
+// JSHeapBroker::DrainJSFunctionCacheWorklist) and must therefore not read
+// cached fields of another JSFunctionData, which may not be cached yet; the
+// DCHECKs in the accessors guard against that. Reading ObjectData kinds and
+// MapData is fine, both are complete once their constructor has run.
void JSFunctionData::Cache(JSHeapBroker* broker) {
DCHECK(!serialized_);
@@ -1235,9 +1247,34 @@ ObjectData* JSHeapBroker::TryGetOrCreateData(IndirectHandle<Object> object,
// At this point the entry pointer is not guaranteed to be valid as
// the refs_ hash hable could be resized by one of the constructors above.
DCHECK_EQ(object_data, refs_->Lookup(object.address())->value);
+
+ DrainJSFunctionCacheWorklist();
+
return object_data;
}
+void JSHeapBroker::AddToJSFunctionCacheWorklist(JSFunctionData* data) {
+ DCHECK_NULL(data->next_in_cache_worklist_);
+ data->next_in_cache_worklist_ = js_function_cache_worklist_;
+ js_function_cache_worklist_ = data;
+}
+
+void JSHeapBroker::DrainJSFunctionCacheWorklist() {
+ // Caching creates data for the function's prototype and thus reenters
+ // TryGetOrCreateData. Such nested calls just add to the worklist; the
+ // outermost call below drains it.
+ if (is_draining_js_function_cache_worklist_) return;
+ ScopedModification<bool> is_draining(&is_draining_js_function_cache_worklist_,
+ true);
+
+ while (js_function_cache_worklist_ != nullptr) {
+ JSFunctionData* data = js_function_cache_worklist_;
+ js_function_cache_worklist_ = data->next_in_cache_worklist_;
+ data->next_in_cache_worklist_ = nullptr;
+ data->Cache(this);
+ }
+}
+
#define DEFINE_IS_AND_AS(Name) \
bool ObjectRef::Is##Name() const { return data()->Is##Name(); } \
Name##Ref ObjectRef::As##Name() const { \
@@ -2154,8 +2191,12 @@ bool ObjectRef::IsNull() const { return i::IsNull(*object()); }
bool ObjectRef::IsUndefined() const { return i::IsUndefined(*object()); }
+bool ObjectRef::IsAnyHole() const { return i::IsAnyHole(*object()); }
+
bool ObjectRef::IsTheHole() const { return i::IsTheHole(*object()); }
+bool ObjectRef::IsTdzHole() const { return i::IsTdzHole(*object()); }
+
bool ObjectRef::IsPropertyCellHole() const {
return i::IsPropertyCellHole(*object());
}
diff --git a/deps/v8/src/compiler/heap-refs.h b/deps/v8/src/compiler/heap-refs.h
index 59195c2824b..3d1f39064ee 100644
--- a/deps/v8/src/compiler/heap-refs.h
+++ b/deps/v8/src/compiler/heap-refs.h
@@ -99,8 +99,11 @@ enum class HoleType : uint8_t {
#define FOR_HOLE(Name, name, Root) k##Name,
HOLE_LIST(FOR_HOLE)
#undef FOR_HOLE
+#ifndef V8_ENABLE_TDZ_HOLE
+ kTdzHole = kTheHole,
+#endif
- kGeneric = kTheHole,
+ kGeneric = kTheHole,
};
enum class RefSerializationKind {
@@ -447,7 +450,9 @@ class V8_EXPORT_PRIVATE ObjectRef {
bool IsNull() const;
bool IsUndefined() const;
enum HoleType HoleType() const;
+ bool IsAnyHole() const;
bool IsTheHole() const;
+ bool IsTdzHole() const;
bool IsPropertyCellHole() const;
bool IsHashTableHole() const;
bool IsPromiseHole() const;
@@ -765,7 +770,7 @@ class HeapNumberRef : public HeapObjectRef {
IndirectHandle<HeapNumber> object() const;
- double value() const;
+ V8_EXPORT_PRIVATE double value() const;
uint64_t value_as_bits() const;
};
diff --git a/deps/v8/src/compiler/js-call-reducer.cc b/deps/v8/src/compiler/js-call-reducer.cc
index 0b4cc9238b1..ef2524264c2 100644
--- a/deps/v8/src/compiler/js-call-reducer.cc
+++ b/deps/v8/src/compiler/js-call-reducer.cc
@@ -8145,7 +8145,7 @@ namespace {
FrameState CreateStringCreateLazyDeoptContinuationFrameState(
JSGraph* graph, SharedFunctionInfoRef shared, Node* target, Node* context,
Node* outer_frame_state) {
- Node* const receiver = graph->TheHoleConstant();
+ Node* const receiver = graph->TdzHoleConstant();
Node* stack_parameters[]{receiver};
const int stack_parameter_count = arraysize(stack_parameters);
return CreateJavaScriptBuiltinContinuationFrameState(
@@ -8535,9 +8535,9 @@ Reduction JSCallReducer::ReduceTypedArrayConstructor(
context, common(), graph());
// This continuation just returns the newly created JSTypedArray. We
- // pass the_hole as the receiver, just like the builtin construct stub
+ // pass tdz_hole as the receiver, just like the builtin construct stub
// does in this case.
- Node* const receiver = jsgraph()->TheHoleConstant();
+ Node* const receiver = jsgraph()->TdzHoleConstant();
Node* continuation_frame_state = CreateGenericLazyDeoptContinuationFrameState(
jsgraph(), shared, target, context, receiver, frame_state);
diff --git a/deps/v8/src/compiler/js-context-specialization.cc b/deps/v8/src/compiler/js-context-specialization.cc
index 79791cf2529..be2b3c4d7e5 100644
--- a/deps/v8/src/compiler/js-context-specialization.cc
+++ b/deps/v8/src/compiler/js-context-specialization.cc
@@ -234,7 +234,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContextNoCell(Node* node) {
// We must be conservative and check if the value in the slot is currently
// the hole or undefined. Only if it is neither of these, can we be sure
// that it won't change anymore.
- if (maybe_value->IsUndefined() || maybe_value->IsTheHole()) {
+ if (maybe_value->IsUndefined() || maybe_value->IsTdzHole()) {
return SimplifyJSLoadContextNoCell(
node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
}
@@ -275,7 +275,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
}
auto maybe_value = concrete.get(broker(), static_cast<int>(access.index()));
- if (!maybe_value || maybe_value->IsTheHole() ||
+ if (!maybe_value || maybe_value->IsTdzHole() ||
maybe_value->IsUndefinedContextCell()) {
return SimplifyJSLoadContext(
node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
@@ -408,7 +408,7 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) {
}
auto maybe_value = concrete.get(broker(), static_cast<int>(access.index()));
- if (!maybe_value || maybe_value->IsTheHole() ||
+ if (!maybe_value || maybe_value->IsTdzHole() ||
maybe_value->IsUndefinedContextCell()) {
return SimplifyJSStoreContext(
node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
@@ -494,11 +494,11 @@ OptionalContextRef GetModuleContext(JSHeapBroker* broker, Node* node,
size_t depth = std::numeric_limits<size_t>::max();
Node* context = NodeProperties::GetOuterContext(node, &depth);
- auto find_context = [broker](ContextRef c) {
+ auto find_context = [broker](ContextRef c) -> OptionalContextRef {
while (c.map(broker).instance_type() != MODULE_CONTEXT_TYPE) {
size_t depth = 1;
c = c.previous(broker, &depth);
- CHECK_EQ(depth, 0);
+ if (depth != 0) return OptionalContextRef();
}
return c;
};
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc
index 22d24ff791a..2affa53f2fb 100644
--- a/deps/v8/src/compiler/js-generic-lowering.cc
+++ b/deps/v8/src/compiler/js-generic-lowering.cc
@@ -710,7 +710,6 @@ void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
}
void JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) {
- node->RemoveInput(4); // control
ReplaceWithBuiltinCall(node, Builtin::kCreateGeneratorObject);
}
diff --git a/deps/v8/src/compiler/js-graph.cc b/deps/v8/src/compiler/js-graph.cc
index f12eac6061e..0690cd343b4 100644
--- a/deps/v8/src/compiler/js-graph.cc
+++ b/deps/v8/src/compiler/js-graph.cc
@@ -79,12 +79,19 @@ Node* JSGraph::Constant(ObjectRef ref, JSHeapBroker* broker) {
return HashTableHoleConstant();
case HoleType::kPromiseHole:
return PromiseHoleConstant();
+#ifdef V8_ENABLE_TDZ_HOLE
+ case HoleType::kTdzHole:
+ return TdzHoleConstant();
+#endif
case HoleType::kOptimizedOut:
return OptimizedOutConstant();
case HoleType::kStaleRegister:
return StaleRegisterConstant();
case HoleType::kUninitializedHole:
return UninitializedConstant();
+#ifndef V8_ENABLE_TDZ_HOLE
+ case HoleType::kDisabledTdzHole:
+#endif
case HoleType::kExceptionHole:
case HoleType::kTerminationException:
case HoleType::kArgumentsMarker:
@@ -261,6 +268,9 @@ DEFINE_GETTER(HashTableHoleConstant, Hole,
DEFINE_GETTER(PromiseHoleConstant, Hole,
HeapConstantHole(factory()->promise_hole_value()))
+DEFINE_GETTER(TdzHoleConstant, Hole,
+ HeapConstantHole(factory()->tdz_hole_value()))
+
DEFINE_GETTER(UninitializedConstant, Hole,
HeapConstantHole(factory()->uninitialized_value()))
diff --git a/deps/v8/src/compiler/js-graph.h b/deps/v8/src/compiler/js-graph.h
index 65e7cfd2980..0054ecbc62b 100644
--- a/deps/v8/src/compiler/js-graph.h
+++ b/deps/v8/src/compiler/js-graph.h
@@ -134,6 +134,7 @@ class V8_EXPORT_PRIVATE JSGraph : public MachineGraph {
V(PropertyCellHoleConstant, Hole) \
V(HashTableHoleConstant, Hole) \
V(PromiseHoleConstant, Hole) \
+ V(TdzHoleConstant, Hole) \
V(UninitializedConstant, Hole) \
V(OptimizedOutConstant, Hole) \
V(StaleRegisterConstant, Hole) \
diff --git a/deps/v8/src/compiler/js-heap-broker.cc b/deps/v8/src/compiler/js-heap-broker.cc
index 2da827a08d6..9c629176c82 100644
--- a/deps/v8/src/compiler/js-heap-broker.cc
+++ b/deps/v8/src/compiler/js-heap-broker.cc
@@ -59,7 +59,10 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
TRACE(this, "Constructing heap broker");
}
-JSHeapBroker::~JSHeapBroker() { DCHECK_NULL(local_isolate_); }
+JSHeapBroker::~JSHeapBroker() {
+ DCHECK_NULL(local_isolate_);
+ DCHECK_NULL(js_function_cache_worklist_);
+}
std::string JSHeapBroker::Trace() const {
std::ostringstream oss;
@@ -667,7 +670,7 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForGlobalAccess(
script_context_index, kAcquireLoad));
OptionalObjectRef contents = context.get(broker, context_slot_index);
- if (contents.has_value()) CHECK(!contents->IsTheHole());
+ if (contents.has_value()) CHECK(!contents->IsTdzHole());
return *zone()->New<GlobalAccessFeedback>(
context, context_slot_index,
diff --git a/deps/v8/src/compiler/js-heap-broker.h b/deps/v8/src/compiler/js-heap-broker.h
index a93433cdbd1..7736a7e3712 100644
--- a/deps/v8/src/compiler/js-heap-broker.h
+++ b/deps/v8/src/compiler/js-heap-broker.h
@@ -392,12 +392,16 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
#define V(Type, name, Name) inline typename ref_traits<Type>::ref_type name();
READ_ONLY_ROOT_LIST(V)
+#ifndef V8_ENABLE_TDZ_HOLE
+ V(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef V
private:
friend class JSHeapBrokerScopeForTesting;
friend class HeapObjectRef;
friend class ObjectRef;
+ friend class JSFunctionData;
friend class ObjectData;
friend class PropertyCellData;
@@ -452,6 +456,15 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
READ_ONLY_ROOT_LIST(V)
#undef V
+ // JSFunctionData::Cache creates data for the function's prototype, which may
+ // be another JSFunction. Caching straight from the constructor would thus
+ // recurse once per link of a prototype chain whose length is under script
+ // control, and overflow the stack. Construction instead only adds to this
+ // worklist, which TryGetOrCreateData drains iteratively before returning; no
+ // caller can observe an uncached JSFunctionData.
+ void AddToJSFunctionCacheWorklist(JSFunctionData* data);
+ void DrainJSFunctionCacheWorklist();
+
Isolate* const isolate_;
#if V8_COMPRESS_POINTERS
const PtrComprCageBase cage_base_;
@@ -468,6 +481,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
// The CanonicalHandlesMap is owned by the compilation info.
CanonicalHandlesMap* canonical_handles_;
unsigned trace_indentation_ = 0;
+ JSFunctionData* js_function_cache_worklist_ = nullptr;
+ bool is_draining_js_function_cache_worklist_ = false;
ZoneUnorderedMap<FeedbackSource, ProcessedFeedback const*,
FeedbackSource::Hash, FeedbackSource::Equal>
feedback_;
@@ -670,6 +685,9 @@ typename ref_traits<T>::ref_type MakeRefAssumeMemoryFence(JSHeapBroker* broker,
}
READ_ONLY_ROOT_LIST(V)
#undef V
+#ifndef V8_ENABLE_TDZ_HOLE
+inline HeapObjectRef JSHeapBroker::tdz_hole_value() { return the_hole_value(); }
+#endif
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/src/compiler/js-inlining.cc b/deps/v8/src/compiler/js-inlining.cc
index bf28bfe87ec..6ee9a688af4 100644
--- a/deps/v8/src/compiler/js-inlining.cc
+++ b/deps/v8/src/compiler/js-inlining.cc
@@ -854,7 +854,7 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
// call, we create an observable deoptimization point after the receiver
// instantiation but before the invocation (i.e. inside {JSConstructStub}
// where execution continues at {construct_stub_create_deopt_pc_offset}).
- Node* receiver = jsgraph()->TheHoleConstant(); // Implicit receiver.
+ Node* receiver = jsgraph()->TdzHoleConstant(); // Implicit receiver.
Node* caller_context = NodeProperties::GetContextInput(node);
if (NeedsImplicitReceiver(*shared_info)) {
Effect effect = n.effect();
diff --git a/deps/v8/src/compiler/js-intrinsic-lowering.cc b/deps/v8/src/compiler/js-intrinsic-lowering.cc
index 2274980adef..6737cfd9eec 100644
--- a/deps/v8/src/compiler/js-intrinsic-lowering.cc
+++ b/deps/v8/src/compiler/js-intrinsic-lowering.cc
@@ -157,8 +157,8 @@ Reduction JSIntrinsicLowering::ReduceCreateJSGeneratorObject(Node* node) {
FrameState frame_state{NodeProperties::GetFrameStateInput(node)};
Operator const* const op = javascript()->CreateGeneratorObject(
frame_state.frame_state_info().bytecode_array().ToHandleChecked());
- Node* create_generator =
- graph()->NewNode(op, closure, receiver, context, effect, control);
+ Node* create_generator = graph()->NewNode(op, closure, receiver, context,
+ frame_state, effect, control);
ReplaceWithValue(node, create_generator, create_generator);
return Changed(create_generator);
}
diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc
index f96471ced31..901ccd3d4a4 100644
--- a/deps/v8/src/compiler/js-native-context-specialization.cc
+++ b/deps/v8/src/compiler/js-native-context-specialization.cc
@@ -2317,9 +2317,9 @@ Reduction JSNativeContextSpecialization::ReduceJSDefineNamedOwnProperty(
JSDefineNamedOwnPropertyNode n(node);
DefineNamedOwnPropertyParameters const& p = n.Parameters();
if (!p.feedback().IsValid()) return NoChange();
- return ReducePropertyAccess(node, nullptr, p.name(), n.value(),
- FeedbackSource(p.feedback()),
- AccessMode::kStoreInLiteral);
+ return ReducePropertyAccess(
+ node, nullptr, p.name(), n.value(), FeedbackSource(p.feedback()),
+ p.in_literal() ? AccessMode::kStoreInLiteral : AccessMode::kDefine);
}
Reduction JSNativeContextSpecialization::ReduceElementAccessOnString(
@@ -3408,7 +3408,8 @@ JSNativeContextSpecialization::BuildPropertyStore(
AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer()),
storage, effect, control);
}
- if (access_info.IsFastDataConstant() && access_mode == AccessMode::kStore &&
+ if (access_info.IsFastDataConstant() &&
+ access_mode != AccessMode::kStoreInLiteral &&
!access_info.HasTransitionMap()) {
Node* deoptimize = graph()->NewNode(
simplified()->CheckIf(DeoptimizeReason::kStoreToConstant),
diff --git a/deps/v8/src/compiler/js-operator.cc b/deps/v8/src/compiler/js-operator.cc
index ac42be61445..5aec87c5ad3 100644
--- a/deps/v8/src/compiler/js-operator.cc
+++ b/deps/v8/src/compiler/js-operator.cc
@@ -222,7 +222,8 @@ CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
bool operator==(DefineNamedOwnPropertyParameters const& lhs,
DefineNamedOwnPropertyParameters const& rhs) {
- return lhs.name_.object().location() == rhs.name_.object().location() &&
+ return lhs.in_literal() == rhs.in_literal() &&
+ lhs.name_.object().location() == rhs.name_.object().location() &&
lhs.feedback() == rhs.feedback();
}
@@ -232,7 +233,7 @@ bool operator!=(DefineNamedOwnPropertyParameters const& lhs,
}
size_t hash_value(DefineNamedOwnPropertyParameters const& p) {
- return base::hash_combine(p.name_.object().location(),
+ return base::hash_combine(p.in_literal(), p.name_.object().location(),
FeedbackSource::Hash()(p.feedback()));
}
@@ -833,11 +834,12 @@ JSWasmCallParameters const& JSWasmCallParametersOf(const Operator* op) {
std::ostream& operator<<(std::ostream& os, JSWasmCallParameters const& p) {
return os << p.native_module() << ", " << p.function_index() << ", "
- << p.feedback();
+ << Brief(*p.shared_fct_info().object()) << ", " << p.feedback();
}
size_t hash_value(JSWasmCallParameters const& p) {
return base::hash_combine(p.native_module(), p.function_index(),
+ p.shared_fct_info().object().location(),
FeedbackSource::Hash()(p.feedback()));
}
@@ -845,6 +847,8 @@ bool operator==(JSWasmCallParameters const& lhs,
JSWasmCallParameters const& rhs) {
return lhs.native_module() == rhs.native_module() &&
lhs.function_index() == rhs.function_index() &&
+ lhs.shared_fct_info().object().location() ==
+ rhs.shared_fct_info().object().location() &&
lhs.feedback() == rhs.feedback();
}
@@ -1336,12 +1340,12 @@ const Operator* JSOperatorBuilder::DefineKeyedOwnProperty(
}
const Operator* JSOperatorBuilder::DefineNamedOwnProperty(
- NameRef name, FeedbackSource const& feedback) {
+ bool in_literal, NameRef name, FeedbackSource const& feedback) {
static constexpr int kObject = 1;
static constexpr int kValue = 1;
static constexpr int kFeedbackVector = 1;
static constexpr int kArity = kObject + kValue + kFeedbackVector;
- DefineNamedOwnPropertyParameters parameters(name, feedback);
+ DefineNamedOwnPropertyParameters parameters(in_literal, name, feedback);
return zone()->New<Operator1<DefineNamedOwnPropertyParameters>>( // --
IrOpcode::kJSDefineNamedOwnProperty, Operator::kNoProperties, // opcode
"JSDefineNamedOwnProperty", // name
@@ -1359,11 +1363,11 @@ const Operator* JSOperatorBuilder::DeleteProperty() {
const Operator* JSOperatorBuilder::CreateGeneratorObject(
IndirectHandle<BytecodeArray> bytecode_array) {
CreateGeneratorObjectParameters parameters(bytecode_array);
- return zone()->New<Operator1<CreateGeneratorObjectParameters>>( // --
- IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable, // opcode
- "JSCreateGeneratorObject", // name
- 2, 1, 1, 1, 1, 0, // counts
- parameters); // parameters
+ return zone()->New<Operator1<CreateGeneratorObjectParameters>>( // --
+ IrOpcode::kJSCreateGeneratorObject, Operator::kNoThrow, // opcode
+ "JSCreateGeneratorObject", // name
+ 2, 1, 1, 1, 1, 0, // counts
+ parameters); // parameters
}
const Operator* JSOperatorBuilder::LoadGlobal(NameRef name,
diff --git a/deps/v8/src/compiler/js-operator.h b/deps/v8/src/compiler/js-operator.h
index 15a49e40b04..80baa97bdb9 100644
--- a/deps/v8/src/compiler/js-operator.h
+++ b/deps/v8/src/compiler/js-operator.h
@@ -418,13 +418,16 @@ CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
// Defines parameters for JSDefineNamedOwnProperty operator.
class DefineNamedOwnPropertyParameters final {
public:
- DefineNamedOwnPropertyParameters(NameRef name, FeedbackSource const& feedback)
- : name_(name), feedback_(feedback) {}
+ DefineNamedOwnPropertyParameters(bool in_literal, NameRef name,
+ FeedbackSource const& feedback)
+ : in_literal_(in_literal), name_(name), feedback_(feedback) {}
NameRef name() const { return name_; }
FeedbackSource const& feedback() const { return feedback_; }
+ bool in_literal() const { return in_literal_; }
private:
+ bool in_literal_;
const NameRef name_;
FeedbackSource const feedback_;
@@ -958,7 +961,7 @@ std::ostream& operator<<(std::ostream&, ForInParameters const&);
const ForInParameters& ForInParametersOf(const Operator* op);
#if V8_ENABLE_WEBASSEMBLY
-class JSWasmCallParameters {
+class JSWasmCallParameters final {
public:
explicit JSWasmCallParameters(wasm::NativeModule* native_module,
int function_index,
@@ -1157,7 +1160,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* SetNamedProperty(LanguageMode language_mode, NameRef name,
FeedbackSource const& feedback);
- const Operator* DefineNamedOwnProperty(NameRef name,
+ const Operator* DefineNamedOwnProperty(bool in_literal, NameRef name,
FeedbackSource const& feedback);
const Operator* DefineKeyedOwnPropertyInLiteral(
const FeedbackSource& feedback);
diff --git a/deps/v8/src/compiler/operator-properties.cc b/deps/v8/src/compiler/operator-properties.cc
index f7e9f16b0ef..e19d1bf0ece 100644
--- a/deps/v8/src/compiler/operator-properties.cc
+++ b/deps/v8/src/compiler/operator-properties.cc
@@ -159,10 +159,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSStrictEqual:
return false;
- // Generator creation cannot call back into arbitrary JavaScript.
- case IrOpcode::kJSCreateGeneratorObject:
- return false;
-
// Binary operations
case IrOpcode::kJSAdd:
case IrOpcode::kJSSubtract:
@@ -203,6 +199,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSCreateLiteralRegExp:
case IrOpcode::kJSCreateObject:
case IrOpcode::kJSCloneObject:
+ case IrOpcode::kJSCreateGeneratorObject:
// Property access operations
case IrOpcode::kJSDeleteProperty:
diff --git a/deps/v8/src/compiler/pipeline-data-inl.h b/deps/v8/src/compiler/pipeline-data-inl.h
index 88b4c3bcd55..6c156325b3c 100644
--- a/deps/v8/src/compiler/pipeline-data-inl.h
+++ b/deps/v8/src/compiler/pipeline-data-inl.h
@@ -44,13 +44,16 @@
namespace v8::internal::compiler {
-inline Maybe<OuterContext> GetModuleContext(OptimizedCompilationInfo* info) {
+inline Maybe<OuterContext> GetModuleOrScriptContext(
+ OptimizedCompilationInfo* info, Isolate* isolate) {
+ DCHECK(v8_flags.always_specialize_for_script_context);
+ if (info->closure().is_null()) return Nothing<OuterContext>();
Tagged<Context> current = info->closure()->context();
size_t distance = 0;
while (!IsNativeContext(current)) {
- if (current->IsModuleContext()) {
- return Just(OuterContext(
- info->CanonicalHandle(current, Isolate::Current()), distance));
+ if (current->IsModuleContext() || current->IsScriptContext()) {
+ return Just(
+ OuterContext(info->CanonicalHandle(current, isolate), distance));
}
current = current->previous();
distance++;
@@ -352,8 +355,8 @@ class TFPipelineData {
DCHECK(info()->has_context());
specialization_context_ = Just(OuterContext(
info()->CanonicalHandle(info()->context(), isolate()), 0));
- } else {
- specialization_context_ = GetModuleContext(info());
+ } else if (v8_flags.always_specialize_for_script_context) {
+ specialization_context_ = GetModuleOrScriptContext(info(), isolate());
}
}
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc
index 13588d79aaa..27f9007b2dd 100644
--- a/deps/v8/src/compiler/pipeline.cc
+++ b/deps/v8/src/compiler/pipeline.cc
@@ -730,6 +730,9 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(
!compilation_info()->is_osr()) {
compilation_info()->set_function_context_specializing();
data_.ChooseSpecializationContext();
+ } else if (v8_flags.always_specialize_for_script_context &&
+ !compilation_info()->is_osr()) {
+ data_.ChooseSpecializationContext();
}
if (compilation_info()->source_positions()) {
@@ -2753,63 +2756,6 @@ void TraceFinishWrapperCompilation(OptimizedCompilationInfo& info,
} // namespace
-// static
-wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
- CallDescriptor* call_descriptor, MachineGraph* mcgraph, CodeKind kind,
- const char* debug_name, const AssemblerOptions& options,
- SourcePositionTable* source_positions) {
- TFGraph* graph = mcgraph->graph();
- OptimizedCompilationInfo info(base::CStrVector(debug_name), graph->zone(),
- kind);
- // Construct a pipeline for scheduling and code generation.
- wasm::WasmEngine* wasm_engine = wasm::GetWasmEngine();
- ZoneStats zone_stats(wasm_engine->allocator());
- NodeOriginTable* node_positions = graph->zone()->New<NodeOriginTable>(graph);
- TFPipelineData data(&zone_stats, wasm_engine, &info, mcgraph, nullptr,
- source_positions, node_positions, options);
- std::unique_ptr<TurbofanPipelineStatistics> pipeline_statistics;
- if (v8_flags.turbo_stats || v8_flags.turbo_stats_nvp) {
- pipeline_statistics.reset(new TurbofanPipelineStatistics(
- &info, wasm_engine->GetOrCreateTurboStatistics(), &zone_stats));
- pipeline_statistics->BeginPhaseKind("V8.WasmStubCodegen");
- }
- TraceWrapperCompilation("TurboFan", &info, &data);
-
- PipelineImpl pipeline(&data);
- pipeline.RunPrintAndVerify("V8.WasmNativeStubMachineCode", true);
-
- CHECK(pipeline.Run<MemoryOptimizationPhase>());
- pipeline.RunPrintAndVerify(MemoryOptimizationPhase::phase_name(), true);
-
- CHECK(pipeline.ComputeScheduledGraph());
-
- Linkage linkage(call_descriptor);
-
- turboshaft::PipelineData turboshaft_data(
- &zone_stats, turboshaft::TurboshaftPipelineKind::kWasm, nullptr, &info,
- options);
- turboshaft::Pipeline turboshaft_pipeline(&turboshaft_data, &linkage);
-
- CHECK(turboshaft_pipeline.CreateGraphFromTurbofan(&data, &linkage));
- // We need to run simplification to normalize some patterns for instruction
- // selection (e.g. loads and stores).
- CHECK(turboshaft_pipeline.RunSimplificationAndNormalizationPhase());
-
- CHECK(GenerateCodeFromTurboshaftGraph(&linkage, turboshaft_pipeline,
- &pipeline, data.osr_helper_ptr()));
-
- auto result = WrapperCompilationResult(turboshaft_data.code_generator(),
- call_descriptor, kind);
- DCHECK(result.succeeded());
- CodeTracer* code_tracer = nullptr;
- if (info.trace_turbo_json() || info.trace_turbo_graph()) {
- code_tracer = data.GetCodeTracer();
- }
- TraceFinishWrapperCompilation(info, code_tracer, result,
- pipeline.code_generator());
- return result;
-}
-
// static
wasm::WasmCompilationResult
Pipeline::GenerateCodeForWasmNativeStubFromTurboshaft(
@@ -3315,19 +3261,17 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
}
}
-// static
-MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
- OptimizedCompilationInfo* info, Isolate* isolate,
- CallDescriptor* call_descriptor, TFGraph* graph,
- const AssemblerOptions& opts, Schedule* schedule) {
- // TODO(nicohartmann): Callers should properly set this, but it's hard to do
- // this through testing logic shared between JS and Wasm.
- AssemblerOptions options = opts;
-#if V8_ENABLE_WEBASSEMBLY
- if (info->IsWasm() || info->IsWasmBuiltin()) {
- options.is_wasm = true;
- }
-#endif
+namespace {
+
+template <typename Finalizer>
+auto GenerateCodeForTestingHelper(OptimizedCompilationInfo* info,
+ Isolate* isolate,
+ CallDescriptor* call_descriptor,
+ TFGraph* graph,
+ const AssemblerOptions& options,
+ Schedule* schedule, Finalizer&& finalize) {
+ using ReturnType = std::invoke_result_t<Finalizer, turboshaft::Pipeline&,
+ turboshaft::PipelineData&>;
// Construct a pipeline for scheduling and code generation.
Linkage linkage(call_descriptor);
ZoneStats zone_stats(isolate->allocator());
@@ -3335,9 +3279,11 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
TFPipelineData data(&zone_stats, info, isolate, isolate->allocator(), graph,
nullptr, schedule, nullptr, node_positions, nullptr,
options, nullptr);
- turboshaft::PipelineData turboshaft_data(
- &zone_stats, turboshaft::TurboshaftPipelineKind::kCSA, isolate, info,
- options);
+ turboshaft::TurboshaftPipelineKind pipeline_kind =
+ options.is_wasm ? turboshaft::TurboshaftPipelineKind::kWasm
+ : turboshaft::TurboshaftPipelineKind::kCSA;
+ turboshaft::PipelineData turboshaft_data(&zone_stats, pipeline_kind, isolate,
+ info, options);
PipelineJobScope scope(&data, isolate->counters()->runtime_call_stats());
std::unique_ptr<TurbofanPipelineStatistics> pipeline_statistics;
if (v8_flags.turbo_stats || v8_flags.turbo_stats_nvp) {
@@ -3364,28 +3310,78 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
// We convert the turbofan graph to turboshaft.
if (!turboshaft_pipeline.CreateGraphFromTurbofan(&data, &linkage)) {
- return {};
+ return ReturnType{};
}
// We need to run simplification to normalize some patterns for instruction
// selection (e.g. loads and stores).
if (!turboshaft_pipeline.RunSimplificationAndNormalizationPhase()) {
- return {};
+ return ReturnType{};
}
if (!GenerateCodeFromTurboshaftGraph(&linkage, turboshaft_pipeline, nullptr,
data.osr_helper_ptr())) {
- return {};
+ return ReturnType{};
}
- MaybeHandle<Code> maybe_code = turboshaft_pipeline.FinalizeCode();
- Handle<Code> code;
- if (maybe_code.ToHandle(&code)) {
- return code;
- }
- return {};
+ return std::forward<Finalizer>(finalize)(turboshaft_pipeline,
+ turboshaft_data);
+}
+
+} // namespace
+
+// static
+MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
+ OptimizedCompilationInfo* info, Isolate* isolate,
+ CallDescriptor* call_descriptor, TFGraph* graph,
+ const AssemblerOptions& options, Schedule* schedule) {
+#if V8_ENABLE_WEBASSEMBLY
+ DCHECK(!info->IsWasm() && !info->IsWasmBuiltin());
+#endif
+ return GenerateCodeForTestingHelper(
+ info, isolate, call_descriptor, graph, options, schedule,
+ [](turboshaft::Pipeline& turboshaft_pipeline, turboshaft::PipelineData&) {
+ return turboshaft_pipeline.FinalizeCode();
+ });
}
+#if V8_ENABLE_WEBASSEMBLY
+// static
+wasm::WasmCompilationResult Pipeline::GenerateWasmCodeForTesting(
+ OptimizedCompilationInfo* info, Isolate* isolate,
+ CallDescriptor* call_descriptor, TFGraph* graph, AssemblerOptions options,
+ Schedule* schedule) {
+ DCHECK(info->IsWasm());
+ options.is_wasm = true;
+ return GenerateCodeForTestingHelper(
+ info, isolate, call_descriptor, graph, options, schedule,
+ [call_descriptor](turboshaft::Pipeline&,
+ turboshaft::PipelineData& turboshaft_data) {
+ CodeGenerator* code_generator = turboshaft_data.code_generator();
+
+ wasm::WasmCompilationResult result;
+ code_generator->masm()->GetCode(
+ nullptr, &result.code_desc,
+ code_generator->safepoint_table_builder(),
+ static_cast<int>(code_generator->handler_table_offset()));
+
+ result.instr_buffer = code_generator->masm()->ReleaseBuffer();
+ result.frame_slot_count =
+ code_generator->frame()->GetTotalFrameSlotCount();
+ result.tagged_parameter_slots =
+ call_descriptor->GetTaggedParameterSlots();
+ result.source_positions = code_generator->GetSourcePositionTable();
+ result.trapping_instructions_data =
+ code_generator->GetTrappingInstructionsData();
+ result.deopt_data = code_generator->GenerateWasmDeoptimizationData();
+ result.result_tier = wasm::ExecutionTier::kTurbofan;
+ result.effect_handlers = code_generator->GenerateWasmEffectHandlers();
+
+ return result;
+ });
+}
+#endif // V8_ENABLE_WEBASSEMBLY
+
// static
MaybeHandle<Code> Pipeline::GenerateTurboshaftCodeForTesting(
CallDescriptor* call_descriptor, turboshaft::PipelineData* data) {
diff --git a/deps/v8/src/compiler/pipeline.h b/deps/v8/src/compiler/pipeline.h
index e0c2870190e..f85efc3a32b 100644
--- a/deps/v8/src/compiler/pipeline.h
+++ b/deps/v8/src/compiler/pipeline.h
@@ -55,9 +55,7 @@ class TFGraph;
class InstructionSequence;
class JSGraph;
class JSHeapBroker;
-class MachineGraph;
class Schedule;
-class SourcePositionTable;
struct WasmCompilationData;
class TFPipelineData;
class ZoneStats;
@@ -119,12 +117,6 @@ class Pipeline : public AllStatic {
const ProfileDataFromFile* profile_data, int finalize_order);
#if V8_ENABLE_WEBASSEMBLY
- // Run the pipeline on a machine graph and generate code.
- static wasm::WasmCompilationResult GenerateCodeForWasmNativeStub(
- CallDescriptor* call_descriptor, MachineGraph* mcgraph, CodeKind kind,
- const char* debug_name, const AssemblerOptions& assembler_options,
- SourcePositionTable* source_positions = nullptr);
-
static wasm::WasmCompilationResult
GenerateCodeForWasmNativeStubFromTurboshaft(
const wasm::CanonicalSig* sig, wasm::WrapperCompilationInfo wrapper_info,
@@ -160,13 +152,25 @@ class Pipeline : public AllStatic {
V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate);
- // Run the pipeline on a machine graph and generate code. If {schedule} is
+ // Run the pipeline on a non-Wasm machine graph and generate code. For Wasm
+ // machine graphs, use {GenerateWasmCodeForTesting}. If {schedule} is
// {nullptr}, then compute a new schedule for code generation.
V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate,
CallDescriptor* call_descriptor, TFGraph* graph,
const AssemblerOptions& options, Schedule* schedule = nullptr);
+#if V8_ENABLE_WEBASSEMBLY
+ // Run the pipeline on a machine graph and compile it into a
+ // {WasmCompilationResult} for testing. Requires {info->IsWasm()}. If
+ // {schedule} is {nullptr}, then compute a new schedule for code generation.
+ V8_EXPORT_PRIVATE static wasm::WasmCompilationResult
+ GenerateWasmCodeForTesting(OptimizedCompilationInfo* info, Isolate* isolate,
+ CallDescriptor* call_descriptor, TFGraph* graph,
+ AssemblerOptions options,
+ Schedule* schedule = nullptr);
+#endif // V8_ENABLE_WEBASSEMBLY
+
// Run the instruction selector on a turboshaft graph and generate code.
V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateTurboshaftCodeForTesting(
CallDescriptor* call_descriptor, turboshaft::PipelineData* data);
diff --git a/deps/v8/src/compiler/refs-map.cc b/deps/v8/src/compiler/refs-map.cc
index f5339b9611f..a2bf0f52a3a 100644
--- a/deps/v8/src/compiler/refs-map.cc
+++ b/deps/v8/src/compiler/refs-map.cc
@@ -4,6 +4,8 @@
#include "src/compiler/refs-map.h"
+#include "src/base/hashing.h"
+
namespace v8 {
namespace internal {
namespace compiler {
@@ -30,7 +32,13 @@ ObjectData* RefsMap::Remove(const Address& key) {
return UnderlyingMap::Remove(key, RefsMap::Hash(key));
}
-uint32_t RefsMap::Hash(Address addr) { return static_cast<uint32_t>(addr); }
+uint32_t RefsMap::Hash(Address addr) {
+ // Don't use a plain cast: keys are handle locations, which are
+ // pointer-aligned and consecutive within a handle block, so they would
+ // fill every eighth bucket in a contiguous run and linear probing would
+ // degrade to a scan.
+ return static_cast<uint32_t>(base::hash64(addr));
+}
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/src/compiler/turboshaft/assembler.h b/deps/v8/src/compiler/turboshaft/assembler.h
index 548f6e5b902..6ab086ea376 100644
--- a/deps/v8/src/compiler/turboshaft/assembler.h
+++ b/deps/v8/src/compiler/turboshaft/assembler.h
@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_TURBOSHAFT_ASSEMBLER_H_
#define V8_COMPILER_TURBOSHAFT_ASSEMBLER_H_
+#include <array>
#include <cstring>
#include <iomanip>
#include <iterator>
@@ -5424,6 +5425,9 @@ class AssemblerOpInterface : public Next {
V<Simd128> Simd128Constant(const uint8_t value[kSimd128Size]) {
return ReduceIfReachableSimd128Constant(value);
}
+ V<Simd128> Simd128Constant(const std::array<uint8_t, kSimd128Size>& value) {
+ return ReduceIfReachableSimd128Constant(value);
+ }
V<Simd128> Simd128Binop(V<Simd128> left, V<Simd128> right,
Simd128BinopOp::Kind kind) {
@@ -5499,6 +5503,11 @@ class AssemblerOpInterface : public Next {
const uint8_t shuffle[kSimd128Size]) {
return ReduceIfReachableSimd128Shuffle(left, right, kind, shuffle);
}
+ V<Simd128> Simd128Shuffle(V<Simd128> left, V<Simd128> right,
+ Simd128ShuffleOp::Kind kind,
+ const std::array<uint8_t, kSimd128Size>& shuffle) {
+ return ReduceIfReachableSimd128Shuffle(left, right, kind, shuffle);
+ }
V<Simd256> Simd128LoadPairDeinterleave(
V<WordPtr> base, V<WordPtr> index, LoadOp::Kind load_kind,
@@ -5512,6 +5521,9 @@ class AssemblerOpInterface : public Next {
V<Simd256> Simd256Constant(const uint8_t value[kSimd256Size]) {
return ReduceIfReachableSimd256Constant(value);
}
+ V<Simd256> Simd256Constant(const std::array<uint8_t, kSimd256Size>& value) {
+ return ReduceIfReachableSimd256Constant(value);
+ }
OpIndex Simd256Extract128Lane(V<Simd256> source, uint8_t lane) {
return ReduceIfReachableSimd256Extract128Lane(source, lane);
diff --git a/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h b/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
index e1eeb5aa42b..9a72d2862a6 100644
--- a/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
+++ b/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
@@ -1186,8 +1186,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadHeapMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
@@ -1200,8 +1199,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadHeapMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
@@ -1252,8 +1250,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteHeapMemory()
.CanAllocateWithoutIdentity()
@@ -1279,8 +1276,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteHeapMemory()
.CanAllocateWithoutIdentity()
@@ -1374,8 +1370,8 @@ struct BuiltinCallDescriptor {
static constexpr OpEffects kEffects = base_effects.CanCallAnything();
};
- struct WasmManagedObjectWait : public Descriptor<WasmManagedObjectWait> {
- static constexpr auto kFunction = Builtin::kWasmManagedObjectWait;
+ struct WasmManagedObjectWait32 : public Descriptor<WasmManagedObjectWait32> {
+ static constexpr auto kFunction = Builtin::kWasmManagedObjectWait32;
using arguments_t = std::tuple<V<HeapObject>, V<Word32>, V<Word32>,
V<HeapObject>, V<BigInt>>;
using results_t = std::tuple<V<Word32>>;
@@ -1386,6 +1382,31 @@ struct BuiltinCallDescriptor {
static constexpr OpEffects kEffects = base_effects.CanCallAnything();
};
+ struct WasmManagedObjectWait64 : public Descriptor<WasmManagedObjectWait64> {
+ static constexpr auto kFunction = Builtin::kWasmManagedObjectWait64;
+ using arguments_t = std::tuple<V<HeapObject>, V<Word32>, V<BigInt>,
+ V<HeapObject>, V<BigInt>>;
+ using results_t = std::tuple<V<Word32>>;
+
+ static constexpr bool kNeedsFrameState = false;
+ static constexpr bool kNeedsContext = false;
+ static constexpr Operator::Properties kProperties = Operator::kNoProperties;
+ static constexpr OpEffects kEffects = base_effects.CanCallAnything();
+ };
+
+ struct WasmManagedObjectWaitRef
+ : public Descriptor<WasmManagedObjectWaitRef> {
+ static constexpr auto kFunction = Builtin::kWasmManagedObjectWaitRef;
+ using arguments_t = std::tuple<V<HeapObject>, V<Word32>, V<Object>,
+ V<HeapObject>, V<BigInt>>;
+ using results_t = std::tuple<V<Word32>>;
+
+ static constexpr bool kNeedsFrameState = false;
+ static constexpr bool kNeedsContext = false;
+ static constexpr Operator::Properties kProperties = Operator::kNoProperties;
+ static constexpr OpEffects kEffects = base_effects.CanCallAnything();
+ };
+
struct WasmWaitqueueNew : public Descriptor<WasmWaitqueueNew> {
static constexpr auto kFunction = Builtin::kWasmWaitqueueNew;
using arguments_t = std::tuple<>;
@@ -1516,8 +1537,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
@@ -1530,8 +1550,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
@@ -1598,8 +1617,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteMemory()
.CanAllocateWithoutIdentity()
@@ -1613,8 +1631,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteMemory()
.CanAllocateWithoutIdentity()
@@ -1667,8 +1684,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteMemory()
.CanAllocateWithoutIdentity()
@@ -1684,8 +1700,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
+ static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanWriteMemory()
.CanAllocateWithoutIdentity()
@@ -1700,7 +1715,8 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties = Operator::kEliminatable;
+ static constexpr Operator::Properties kProperties =
+ Operator::kNoDeopt | Operator::kNoWrite;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
@@ -1713,7 +1729,8 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties = Operator::kEliminatable;
+ static constexpr Operator::Properties kProperties =
+ Operator::kNoDeopt | Operator::kNoWrite;
static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
diff --git a/deps/v8/src/compiler/turboshaft/fast-api-call-lowering-reducer.h b/deps/v8/src/compiler/turboshaft/fast-api-call-lowering-reducer.h
index 0e27025009b..c34b194d2e0 100644
--- a/deps/v8/src/compiler/turboshaft/fast-api-call-lowering-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/fast-api-call-lowering-reducer.h
@@ -86,9 +86,12 @@ class FastApiCallLoweringReducer : public Next {
offsetof(v8::FastApiCallbackOptions, isolate));
// data = data_argument
OpIndex data_argument_to_pass = __ AdaptLocalArgument(data_argument);
+ START_ALLOW_USE_DEPRECATED()
+ constexpr size_t data_offset =
+ offsetof(v8::FastApiCallbackOptions, data);
+ END_ALLOW_USE_DEPRECATED()
__ StoreOffHeap(stack_slot, data_argument_to_pass,
- MemoryRepresentation::UintPtr(),
- offsetof(v8::FastApiCallbackOptions, data));
+ MemoryRepresentation::UintPtr(), data_offset);
args.push_back(stack_slot);
builder.AddParam(MachineType::Pointer());
diff --git a/deps/v8/src/compiler/turboshaft/fast-hash.h b/deps/v8/src/compiler/turboshaft/fast-hash.h
index 4fe009f1d2e..7a8dda1df87 100644
--- a/deps/v8/src/compiler/turboshaft/fast-hash.h
+++ b/deps/v8/src/compiler/turboshaft/fast-hash.h
@@ -5,11 +5,14 @@
#ifndef V8_COMPILER_TURBOSHAFT_FAST_HASH_H_
#define V8_COMPILER_TURBOSHAFT_FAST_HASH_H_
+#include <array>
#include <optional>
#include <tuple>
#include "src/base/hashing.h"
#include "src/base/vector.h"
+#include "src/handles/handles.h"
+#include "src/handles/maybe-handles.h"
namespace v8::internal::compiler::turboshaft {
@@ -84,6 +87,27 @@ struct fast_hash<base::Vector<T>> {
}
};
+template <typename T>
+struct fast_hash<IndirectHandle<T>> {
+ V8_INLINE size_t operator()(IndirectHandle<T> v) const {
+ return fast_hash<Address>()(v.address());
+ }
+};
+
+template <typename T>
+struct fast_hash<MaybeIndirectHandle<T>> {
+ V8_INLINE size_t operator()(MaybeIndirectHandle<T> v) const {
+ return fast_hash<Address>()(v.address());
+ }
+};
+
+template <typename T, size_t N>
+struct fast_hash<std::array<T, N>> {
+ V8_INLINE size_t operator()(const std::array<T, N>& v) const {
+ return fast_hash_range(v.begin(), v.end());
+ }
+};
+
} // namespace v8::internal::compiler::turboshaft
#endif // V8_COMPILER_TURBOSHAFT_FAST_HASH_H_
diff --git a/deps/v8/src/compiler/turboshaft/instruction-selection-normalization-reducer.h b/deps/v8/src/compiler/turboshaft/instruction-selection-normalization-reducer.h
index a600028f638..d8f2d73c46c 100644
--- a/deps/v8/src/compiler/turboshaft/instruction-selection-normalization-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/instruction-selection-normalization-reducer.h
@@ -23,6 +23,9 @@ namespace v8::internal::compiler::turboshaft {
// binary operations.
//
// * Replacing multiplications by small powers of 2 with shifts.
+//
+// * Splitting widening SIMD loads into 64-bit zero-extending loads and
+// low-half extensions on ARM64.
#include "src/compiler/turboshaft/define-assembler-macros.inc"
@@ -67,6 +70,45 @@ class InstructionSelectionNormalizationReducer : public Next {
return Next::ReduceComparison(left, right, kind, rep);
}
+#if V8_ENABLE_SIMD128 && V8_TARGET_ARCH_ARM64
+ V<Simd128> REDUCE(Simd128LoadTransform)(
+ V<WordPtr> base, V<WordPtr> index,
+ Simd128LoadTransformOp::LoadKind load_kind,
+ Simd128LoadTransformOp::TransformKind transform_kind, int offset) {
+ using TransformKind = Simd128LoadTransformOp::TransformKind;
+ using UnaryKind = Simd128UnaryOp::Kind;
+
+ UnaryKind extension_kind;
+ switch (transform_kind) {
+ case TransformKind::k8x8S:
+ extension_kind = UnaryKind::kI16x8SConvertI8x16Low;
+ break;
+ case TransformKind::k8x8U:
+ extension_kind = UnaryKind::kI16x8UConvertI8x16Low;
+ break;
+ case TransformKind::k16x4S:
+ extension_kind = UnaryKind::kI32x4SConvertI16x8Low;
+ break;
+ case TransformKind::k16x4U:
+ extension_kind = UnaryKind::kI32x4UConvertI16x8Low;
+ break;
+ case TransformKind::k32x2S:
+ extension_kind = UnaryKind::kI64x2SConvertI32x4Low;
+ break;
+ case TransformKind::k32x2U:
+ extension_kind = UnaryKind::kI64x2UConvertI32x4Low;
+ break;
+ default:
+ return Next::ReduceSimd128LoadTransform(base, index, load_kind,
+ transform_kind, offset);
+ }
+
+ V<Simd128> load = __ Simd128LoadTransform(base, index, load_kind,
+ TransformKind::k64Zero, offset);
+ return __ Simd128Unary(load, extension_kind);
+ }
+#endif // V8_ENABLE_SIMD128 && V8_TARGET_ARCH_ARM64
+
private:
// Return true if {index} is a literal ConsantOp.
bool IsSimpleConstant(V<Any> index) {
diff --git a/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h b/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h
index fe618692f15..260dbae93ec 100644
--- a/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h
@@ -961,13 +961,7 @@ class V8_EXPORT_PRIVATE LateLoadEliminationReducer : public Next {
Asm().output_graph().IsCreatedFromTurbofan(),
Asm().output_graph().IsTurbolev()));
}
-#if DEBUG_BOOL && V8_STATIC_ROOTS_BOOL
- // Note that this verification is only enabled on builds with static
- // roots enabled, because this simplifies the comparison of string maps:
- // with static roots we can know easily if a tagged value is a string
- // map, while without static roots, we'd have to load the instance type,
- // which requires to first check if it's actually a map or not.
-
+#if DEBUG
if (v8_flags.turboshaft_verify_load_elimination) {
// When the debug flag {turboshaft_verify_load_elimination} is used,
// we perform the original load and assert that it's indeed equal to
@@ -1015,7 +1009,7 @@ class V8_EXPORT_PRIVATE LateLoadEliminationReducer : public Next {
__ Equal(actual_idx, actual_idx, actual_rep),
__ Equal(replacement_idx, replacement_idx,
replacement_rep))) {
- // At least one of {actual_idx} and {reaplcement_idx} is not
+ // At least one of {actual_idx} and {replacement_idx} is not
// NaN.
EmitReportLoadEliminationError();
}
@@ -1024,7 +1018,7 @@ class V8_EXPORT_PRIVATE LateLoadEliminationReducer : public Next {
}
}
}
-#endif // DEBUG_BOOL && V8_STATIC_ROOTS_BOOL
+#endif // DEBUG
return replacement_idx;
} else if (replacement.IsTaggedLoadToInt32Load()) {
auto loaded_rep = load.loaded_rep;
diff --git a/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h b/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
index 3e2b973e078..f31fc86cefa 100644
--- a/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
@@ -1621,13 +1621,10 @@ class MachineOptimizationReducer : public Next {
matcher_.TryCast<Word64AddSub128BinopOp>(p0->input());
if (!nested) return nullptr;
if (nested->kind != Word64AddSub128BinopOp::Kind::kAdd) return nullptr;
- int64_t cx, cy, cz;
- if (!matcher_.MatchIntegralWord64Constant(nested->left_high(), &cx) ||
- !matcher_.MatchIntegralWord64Constant(nested->right_high(), &cy) ||
- !matcher_.MatchIntegralWord64Constant(bh, &cz)) {
+ if (!matcher_.MatchZero(nested->left_high()) ||
+ !matcher_.MatchZero(nested->right_high()) || !matcher_.MatchZero(bh)) {
return nullptr;
}
- if (cx != 0 || cy != 0 || cz != 0) return nullptr;
return nested;
}
@@ -1638,8 +1635,8 @@ class MachineOptimizationReducer : public Next {
return Next::ReduceWord64AddSub128Binop(al, ah, bl, bh, kind);
}
- // TODO(ryandiaz): implement on arm64
-#ifdef V8_TARGET_ARCH_X64
+#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) || \
+ defined(V8_TARGET_ARCH_LOONG64) || defined(V8_TARGET_ARCH_MIPS64)
if (kind == Word64AddSub128BinopOp::Kind::kAdd) {
// add128(add128(x, 0, y, 0), z, 0) -> add3(x, y, z)
if (const Word64AddSub128BinopOp* nested = TryMatchAdd3(al, ah, bh)) {
@@ -1650,11 +1647,11 @@ class MachineOptimizationReducer : public Next {
if (const Word64AddSub128BinopOp* nested = TryMatchAdd3(bl, bh, ah)) {
return __ Word64Add3(al, nested->left_low(), nested->right_low());
}
-
- // TODO(ryandiaz): sub128(sub128(x, 0, y, 0), z, 0) -> sub2(x, y, z)
- // TODO(ryandiaz): sub128(x, 0, add128(y, 0, z, 0)) -> sub2(x, y, z)
}
-#endif // V8_TARGET_ARCH_X64
+ // TODO(ryandiaz): sub128(sub128(x, 0, y, 0), z, 0) -> sub2(x, y, z)
+ // TODO(ryandiaz): sub128(x, 0, add128(y, 0, z, 0)) -> sub2(x, y, z)
+#endif // defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) ||
+ // defined(V8_TARGET_ARCH_LOONG64) || defined(V8_TARGET_ARCH_MIPS64)
return Next::ReduceWord64AddSub128Binop(al, ah, bl, bh, kind);
}
@@ -2694,10 +2691,10 @@ class MachineOptimizationReducer : public Next {
goto no_change;
case MachineRepresentation::kWord8: {
if (shuffles.size() == 4) {
- const uint8_t* shuffle1 = shuffles[0]->shuffle;
- const uint8_t* shuffle2 = shuffles[1]->shuffle;
- const uint8_t* shuffle3 = shuffles[2]->shuffle;
- const uint8_t* shuffle4 = shuffles[3]->shuffle;
+ const uint8_t* shuffle1 = shuffles[0]->shuffle.data();
+ const uint8_t* shuffle2 = shuffles[1]->shuffle.data();
+ const uint8_t* shuffle3 = shuffles[2]->shuffle.data();
+ const uint8_t* shuffle4 = shuffles[3]->shuffle.data();
if (SimdShuffle::TryMatch8x16UpperToLowerReduce(shuffle1, shuffle2,
shuffle3, shuffle4)) {
V<Simd128> reduce = __ Simd128Reduce(
@@ -2709,9 +2706,9 @@ class MachineOptimizationReducer : public Next {
}
case MachineRepresentation::kWord16: {
if (shuffles.size() == 3) {
- const uint8_t* shuffle1 = shuffles[0]->shuffle;
- const uint8_t* shuffle2 = shuffles[1]->shuffle;
- const uint8_t* shuffle3 = shuffles[2]->shuffle;
+ const uint8_t* shuffle1 = shuffles[0]->shuffle.data();
+ const uint8_t* shuffle2 = shuffles[1]->shuffle.data();
+ const uint8_t* shuffle3 = shuffles[2]->shuffle.data();
if (SimdShuffle::TryMatch16x8UpperToLowerReduce(shuffle1, shuffle2,
shuffle3)) {
V<Simd128> reduce = __ Simd128Reduce(
@@ -2723,8 +2720,8 @@ class MachineOptimizationReducer : public Next {
}
case MachineRepresentation::kWord32: {
if (shuffles.size() == 2) {
- const uint8_t* shuffle1 = shuffles[0]->shuffle;
- const uint8_t* shuffle2 = shuffles[1]->shuffle;
+ const uint8_t* shuffle1 = shuffles[0]->shuffle.data();
+ const uint8_t* shuffle2 = shuffles[1]->shuffle.data();
if (SimdShuffle::TryMatch32x4UpperToLowerReduce(shuffle1, shuffle2)) {
V<Simd128> reduce = __ Simd128Reduce(
reduce_input, Simd128ReduceOp::Kind::kI32x4AddReduce);
@@ -2735,8 +2732,8 @@ class MachineOptimizationReducer : public Next {
}
case MachineRepresentation::kFloat32: {
if (shuffles.size() == 2) {
- const uint8_t* shuffle1 = shuffles[0]->shuffle;
- const uint8_t* shuffle2 = shuffles[1]->shuffle;
+ const uint8_t* shuffle1 = shuffles[0]->shuffle.data();
+ const uint8_t* shuffle2 = shuffles[1]->shuffle.data();
if (SimdShuffle::TryMatch32x4PairwiseReduce(shuffle1, shuffle2)) {
V<Simd128> reduce = __ Simd128Reduce(
reduce_input, Simd128ReduceOp::Kind::kF32x4AddReduce);
@@ -2749,7 +2746,7 @@ class MachineOptimizationReducer : public Next {
case MachineRepresentation::kFloat64: {
if (shuffles.size() == 1) {
uint8_t shuffle64x2[2];
- if (SimdShuffle::TryMatch64x2Shuffle(shuffles[0]->shuffle,
+ if (SimdShuffle::TryMatch64x2Shuffle(shuffles[0]->shuffle.data(),
shuffle64x2) &&
SimdShuffle::TryMatch64x2Reduce(shuffle64x2)) {
V<Simd128> reduce =
@@ -2782,7 +2779,7 @@ class MachineOptimizationReducer : public Next {
switch (lane) {
case 0:
- return __ Simd128Constant(constant_input->value);
+ return __ Simd128Constant(constant_input->value.data());
case 1:
return __ Simd128Constant(&constant_input->value[kSimd256Size / 2]);
default:
diff --git a/deps/v8/src/compiler/turboshaft/operations.cc b/deps/v8/src/compiler/turboshaft/operations.cc
index a944a0d953b..af0c5b0b3fc 100644
--- a/deps/v8/src/compiler/turboshaft/operations.cc
+++ b/deps/v8/src/compiler/turboshaft/operations.cc
@@ -4,6 +4,7 @@
#include "src/compiler/turboshaft/operations.h"
+#include <array>
#include <atomic>
#include <iomanip>
#include <optional>
@@ -759,6 +760,9 @@ void StoreOp::PrintOptions(std::ostream& os) const {
}
if (offset != 0) os << ", offset: " << offset;
if (maybe_initializing_or_transitioning) os << ", initializing";
+ if (indirect_pointer_tag() != kIndirectPointerNullTag) {
+ os << ", indirect pointer tag: " << indirect_pointer_tag();
+ }
os << ']';
}
@@ -1811,7 +1815,7 @@ const RegisterRepresentation& RepresentationFor(wasm::ValueType type) {
#if V8_ENABLE_SIMD128
namespace {
template <size_t size>
-void PrintSimdValue(std::ostream& os, const uint8_t (&value)[size]) {
+void PrintSimdValue(std::ostream& os, const std::array<uint8_t, size>& value) {
os << "0x" << std::hex << std::setfill('0');
#ifdef V8_TARGET_BIG_ENDIAN
for (int i = 0; i < static_cast<int>(size); i++) {
diff --git a/deps/v8/src/compiler/turboshaft/operations.h b/deps/v8/src/compiler/turboshaft/operations.h
index e1ea2f66a84..4d62936f230 100644
--- a/deps/v8/src/compiler/turboshaft/operations.h
+++ b/deps/v8/src/compiler/turboshaft/operations.h
@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_TURBOSHAFT_OPERATIONS_H_
#define V8_COMPILER_TURBOSHAFT_OPERATIONS_H_
+#include <array>
#include <cmath>
#include <cstdint>
#include <cstring>
@@ -1103,6 +1104,64 @@ template <class Op>
struct HasStaticEffects<Op, std::void_t<decltype(Op::effects)>>
: std::bool_constant<true> {};
+namespace detail {
+template <typename T>
+bool OptionEquals(const T& a, const T& b) {
+ return a == b;
+}
+template <typename T>
+bool OptionEquals(IndirectHandle<T> a, IndirectHandle<T> b) {
+ return a.equals(b);
+}
+template <typename T>
+bool OptionEquals(MaybeIndirectHandle<T> a, MaybeIndirectHandle<T> b) {
+ return a.equals(b);
+}
+template <typename Tuple, size_t... I>
+bool OptionsTupleEquals(const Tuple& a, const Tuple& b,
+ std::index_sequence<I...>) {
+ return (OptionEquals(std::get<I>(a), std::get<I>(b)) && ...);
+}
+
+// Detects options that the default `operator==` and `hash_value` below would
+// compare and hash by address instead of by value.
+//
+// A raw C array decays to a pointer when the options tuple is built, so an
+// operation that puts one in `options()` silently gets address comparison.
+// Pointers to class types are fine: options like `Block*` or
+// `wasm::StructType*` point to interned objects and are meant to be compared
+// by identity. `const char*` is fine for the same reason, it denotes a string
+// literal. Note that `uint8_t` is `unsigned char`, a distinct type from
+// `char`, so string options stay allowed while decayed byte arrays are caught.
+template <typename T>
+struct IsComparedByAddress {
+ using Type = std::remove_cvref_t<T>;
+ using Pointee = std::remove_cv_t<std::remove_pointer_t<Type>>;
+ static constexpr bool value =
+ std::is_array_v<Type> ||
+ (std::is_pointer_v<Type> && std::is_arithmetic_v<Pointee> &&
+ !std::is_same_v<Pointee, char>);
+};
+
+template <typename Options>
+struct OptionsAreComparedByValue;
+template <typename... Ts>
+struct OptionsAreComparedByValue<std::tuple<Ts...>>
+ : std::bool_constant<(!IsComparedByAddress<Ts>::value && ...)> {};
+
+template <typename Options>
+constexpr void CheckOptionsAreComparedByValue() {
+ // Checking this here rather than in the class body is required: `Derived`
+ // is still incomplete while this CRTP base is instantiated, so `options()`
+ // can only be inspected from a member function body. This also limits the
+ // check to operations that actually use the default comparison, rather
+ // than ones that define their own `operator==` or `hash_value`.
+ static_assert(OptionsAreComparedByValue<std::remove_cvref_t<Options>>::value,
+ "options() must not contain a raw C array, it decays to a "
+ "pointer and would be compared by address. Use std::array.");
+}
+} // namespace detail
+
// This template knows the complete type of the operation and is plugged into
// the inheritance hierarchy. It removes boilerplate from the concrete
// `Operation` subclasses, defining everything that can be expressed
@@ -1229,8 +1288,15 @@ struct OperationT : Operation {
return derived_this() == other.derived_this();
}
bool operator==(const Base& other) const {
+ detail::CheckOptionsAreComparedByValue<
+ decltype(derived_this().options())>();
+ auto lhs_options = derived_this().options();
+ auto rhs_options = other.derived_this().options();
return derived_this().inputs() == other.derived_this().inputs() &&
- derived_this().options() == other.derived_this().options();
+ detail::OptionsTupleEquals(
+ lhs_options, rhs_options,
+ std::make_index_sequence<
+ std::tuple_size_v<decltype(lhs_options)>>{});
}
template <typename... Args>
size_t HashWithOptions(const Args&... args) const {
@@ -1238,6 +1304,8 @@ struct OperationT : Operation {
}
size_t hash_value(
HashingStrategy strategy = HashingStrategy::kDefault) const {
+ detail::CheckOptionsAreComparedByValue<
+ decltype(derived_this().options())>();
return HashWithOptions(derived_this().options());
}
@@ -1827,6 +1895,9 @@ struct Word64MulWideOp : FixedArityOperationT<2, Word64MulWideOp> {
void PrintOptions(std::ostream& os) const;
};
+// 3-way 64-bit addition: computes (a + b + c) returning a pair of Word64:
+// - projection 0: low 64-bit sum ((a + b + c) mod 2^64)
+// - projection 1: carry-out ((a + b + c) >> 64, with values in {0, 1, 2})
struct Word64Add3Op : FixedArityOperationT<3, Word64Add3Op> {
static constexpr OpEffects effects = OpEffects();
@@ -3045,9 +3116,6 @@ struct LoadOp : OperationT<LoadOp> {
bool maybe_unaligned : 1;
// There is a Wasm trap handler for out-of-bounds accesses.
bool with_trap_handler : 1;
- // The wasm trap handler is used for null accesses. Note that this requires
- // with_trap_handler as well.
- bool trap_on_null : 1;
// If {load_eliminable} is true, then:
// - Stores/Loads at this address cannot overlap. Concretely, it means
// that something like this cannot happen:
@@ -3095,7 +3163,6 @@ struct LoadOp : OperationT<LoadOp> {
return {.tagged_base = true,
.maybe_unaligned = false,
.with_trap_handler = false,
- .trap_on_null = false,
.load_eliminable = true,
.is_immutable = false,
.is_atomic = false};
@@ -3104,7 +3171,6 @@ struct LoadOp : OperationT<LoadOp> {
return {.tagged_base = false,
.maybe_unaligned = false,
.with_trap_handler = false,
- .trap_on_null = false,
.load_eliminable = true,
.is_immutable = false,
.is_atomic = false};
@@ -3113,7 +3179,6 @@ struct LoadOp : OperationT<LoadOp> {
return {.tagged_base = false,
.maybe_unaligned = true,
.with_trap_handler = false,
- .trap_on_null = false,
.load_eliminable = true,
.is_immutable = false,
.is_atomic = false};
@@ -3122,7 +3187,6 @@ struct LoadOp : OperationT<LoadOp> {
return {.tagged_base = false,
.maybe_unaligned = false,
.with_trap_handler = true,
- .trap_on_null = false,
.load_eliminable = true,
.is_immutable = false,
.is_atomic = false};
@@ -3131,7 +3195,6 @@ struct LoadOp : OperationT<LoadOp> {
return {.tagged_base = true,
.maybe_unaligned = false,
.with_trap_handler = true,
- .trap_on_null = true,
.load_eliminable = true,
.is_immutable = false,
.is_atomic = false};
@@ -3167,8 +3230,7 @@ struct LoadOp : OperationT<LoadOp> {
maybe_unaligned == other.maybe_unaligned &&
with_trap_handler == other.with_trap_handler &&
load_eliminable == other.load_eliminable &&
- is_immutable == other.is_immutable &&
- is_atomic == other.is_atomic && trap_on_null == other.trap_on_null;
+ is_immutable == other.is_immutable && is_atomic == other.is_atomic;
}
};
Kind kind;
@@ -3771,7 +3833,8 @@ struct StoreOp : OperationT<StoreOp> {
memory_order(),
offset,
element_size_log2,
- maybe_initializing_or_transitioning};
+ maybe_initializing_or_transitioning,
+ indirect_pointer_tag()};
}
};
@@ -6807,17 +6870,6 @@ struct TransitionAndStoreArrayElementOp
UNREACHABLE();
}
- size_t hash_value(
- HashingStrategy strategy = HashingStrategy::kDefault) const {
- DCHECK_EQ(strategy, HashingStrategy::kDefault);
- return HashWithOptions(fast_map.address(), double_map.address());
- }
-
- bool operator==(const TransitionAndStoreArrayElementOp& other) const {
- return kind == other.kind && fast_map.equals(other.fast_map) &&
- double_map.equals(other.double_map);
- }
-
auto options() const { return std::tuple{kind, fast_map, double_map}; }
};
@@ -7027,15 +7079,6 @@ struct CheckedClosureOp : FixedArityOperationT<2, CheckedClosureOp> {
DCHECK(Get(graph, frame_state()).Is<FrameStateOp>());
}
- bool operator==(const CheckedClosureOp& other) const {
- return feedback_cell.address() == other.feedback_cell.address();
- }
- size_t hash_value(
- HashingStrategy strategy = HashingStrategy::kDefault) const {
- DCHECK_EQ(strategy, HashingStrategy::kDefault);
- return HashWithOptions(feedback_cell.address());
- }
-
auto options() const { return std::tuple{feedback_cell}; }
};
@@ -8658,14 +8701,17 @@ struct StringPrepareForGetCodeUnitOp
struct Simd128ConstantOp : FixedArityOperationT<0, Simd128ConstantOp> {
static constexpr uint8_t kZero[kSimd128Size] = {};
- uint8_t value[kSimd128Size];
+ std::array<uint8_t, kSimd128Size> value;
static constexpr OpEffects effects = OpEffects();
explicit Simd128ConstantOp(const uint8_t incoming_value[kSimd128Size])
: Base() {
- std::copy(incoming_value, incoming_value + kSimd128Size, value);
+ std::copy(incoming_value, incoming_value + kSimd128Size, value.begin());
}
+ explicit Simd128ConstantOp(
+ const std::array<uint8_t, kSimd128Size>& incoming_value)
+ : Base(), value(incoming_value) {}
base::Vector<const RegisterRepresentation> outputs_rep() const {
return RepVector<RegisterRepresentation::Simd128()>();
@@ -8680,18 +8726,11 @@ struct Simd128ConstantOp : FixedArityOperationT<0, Simd128ConstantOp> {
// TODO(14108): Validate.
}
- bool IsZero() const { return std::memcmp(kZero, value, kSimd128Size) == 0; }
+ bool IsZero() const {
+ return std::memcmp(kZero, value.data(), kSimd128Size) == 0;
+ }
auto options() const { return std::tuple{value}; }
- // {options()} decays {value} to a pointer, so the inherited {operator==} and
- // {hash_value} would compare addresses.
- bool operator==(const Simd128ConstantOp& other) const {
- return std::memcmp(value, other.value, kSimd128Size) == 0;
- }
- size_t hash_value(
- HashingStrategy strategy = HashingStrategy::kDefault) const {
- return HashWithOptions(base::VectorOf(value));
- }
void PrintOptions(std::ostream& os) const;
};
@@ -8873,6 +8912,140 @@ struct Simd128BinopOp : FixedArityOperationT<2, Simd128BinopOp> {
}
}
+ static bool IsLaneWise(Kind kind) {
+ // Preserve lane count and operate on corresponding lanes independently.
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI16x8ExtMulLowI8x16S:
+ case Kind::kI16x8ExtMulHighI8x16S:
+ case Kind::kI16x8ExtMulLowI8x16U:
+ case Kind::kI16x8ExtMulHighI8x16U:
+ case Kind::kI32x4ExtMulLowI16x8S:
+ case Kind::kI32x4ExtMulHighI16x8S:
+ case Kind::kI32x4ExtMulLowI16x8U:
+ case Kind::kI32x4ExtMulHighI16x8U:
+ case Kind::kI64x2ExtMulLowI32x4S:
+ case Kind::kI64x2ExtMulHighI32x4S:
+ case Kind::kI64x2ExtMulLowI32x4U:
+ case Kind::kI64x2ExtMulHighI32x4U:
+ case Kind::kI8x16SConvertI16x8:
+ case Kind::kI8x16UConvertI16x8:
+ case Kind::kI16x8SConvertI32x4:
+ case Kind::kI16x8UConvertI32x4:
+ return false;
+ case Kind::kI8x16Swizzle:
+ case Kind::kI8x16RelaxedSwizzle:
+ case Kind::kI32x4DotI16x8S:
+ case Kind::kI16x8DotI8x16I7x16S:
+ case Kind::kI32x4AddPairwise:
+ case Kind::kI32x4DotI8x16S:
+ return false;
+ case Kind::kI8x16Eq:
+ case Kind::kI8x16Ne:
+ case Kind::kI8x16GtS:
+ case Kind::kI8x16GtU:
+ case Kind::kI8x16GeS:
+ case Kind::kI8x16GeU:
+ case Kind::kI16x8Eq:
+ case Kind::kI16x8Ne:
+ case Kind::kI16x8GtS:
+ case Kind::kI16x8GtU:
+ case Kind::kI16x8GeS:
+ case Kind::kI16x8GeU:
+ case Kind::kI32x4Eq:
+ case Kind::kI32x4Ne:
+ case Kind::kI32x4GtS:
+ case Kind::kI32x4GtU:
+ case Kind::kI32x4GeS:
+ case Kind::kI32x4GeU:
+ case Kind::kF32x4Eq:
+ case Kind::kF32x4Ne:
+ case Kind::kF32x4Lt:
+ case Kind::kF32x4Le:
+ case Kind::kF64x2Eq:
+ case Kind::kF64x2Ne:
+ case Kind::kF64x2Lt:
+ case Kind::kF64x2Le:
+ case Kind::kS128And:
+ case Kind::kS128AndNot:
+ case Kind::kS128Or:
+ case Kind::kS128Xor:
+ case Kind::kI8x16Add:
+ case Kind::kI8x16AddSatS:
+ case Kind::kI8x16AddSatU:
+ case Kind::kI8x16Sub:
+ case Kind::kI8x16SubSatS:
+ case Kind::kI8x16SubSatU:
+ case Kind::kI8x16MinS:
+ case Kind::kI8x16MinU:
+ case Kind::kI8x16MaxS:
+ case Kind::kI8x16MaxU:
+ case Kind::kI8x16RoundingAverageU:
+ case Kind::kI16x8Q15MulRSatS:
+ case Kind::kI16x8Add:
+ case Kind::kI16x8AddSatS:
+ case Kind::kI16x8AddSatU:
+ case Kind::kI16x8Sub:
+ case Kind::kI16x8SubSatS:
+ case Kind::kI16x8SubSatU:
+ case Kind::kI16x8Mul:
+ case Kind::kI16x8MinS:
+ case Kind::kI16x8MinU:
+ case Kind::kI16x8MaxS:
+ case Kind::kI16x8MaxU:
+ case Kind::kI16x8RoundingAverageU:
+ case Kind::kI32x4Add:
+ case Kind::kI32x4Sub:
+ case Kind::kI32x4Mul:
+ case Kind::kI32x4MinS:
+ case Kind::kI32x4MinU:
+ case Kind::kI32x4MaxS:
+ case Kind::kI32x4MaxU:
+ case Kind::kI64x2Add:
+ case Kind::kI64x2Sub:
+ case Kind::kI64x2Mul:
+ case Kind::kI64x2Eq:
+ case Kind::kI64x2Ne:
+ case Kind::kI64x2GtS:
+ case Kind::kI64x2GeS:
+ case Kind::kF32x4Add:
+ case Kind::kF32x4Sub:
+ case Kind::kF32x4Mul:
+ case Kind::kF32x4Div:
+ case Kind::kF32x4Min:
+ case Kind::kF32x4Max:
+ case Kind::kF32x4Pmin:
+ case Kind::kF32x4Pmax:
+ case Kind::kF64x2Add:
+ case Kind::kF64x2Sub:
+ case Kind::kF64x2Mul:
+ case Kind::kF64x2Div:
+ case Kind::kF64x2Min:
+ case Kind::kF64x2Max:
+ case Kind::kF64x2Pmin:
+ case Kind::kF64x2Pmax:
+ case Kind::kF32x4RelaxedMin:
+ case Kind::kF32x4RelaxedMax:
+ case Kind::kF64x2RelaxedMin:
+ case Kind::kF64x2RelaxedMax:
+ case Kind::kI16x8RelaxedQ15MulRS:
+ case Kind::kF16x8Add:
+ case Kind::kF16x8Sub:
+ case Kind::kF16x8Mul:
+ case Kind::kF16x8Div:
+ case Kind::kF16x8Min:
+ case Kind::kF16x8Max:
+ case Kind::kF16x8Pmin:
+ case Kind::kF16x8Pmax:
+ case Kind::kF16x8Eq:
+ case Kind::kF16x8Ne:
+ case Kind::kF16x8Lt:
+ case Kind::kF16x8Le:
+ return true;
+ }
+ }
+
static constexpr OpEffects effects = OpEffects();
base::Vector<const RegisterRepresentation> outputs_rep() const {
@@ -8891,6 +9064,140 @@ struct Simd128BinopOp : FixedArityOperationT<2, Simd128BinopOp> {
V<Simd128> left() const { return input<Simd128>(0); }
V<Simd128> right() const { return input<Simd128>(1); }
+ static MachineRepresentation input_element_rep(Kind kind) {
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI8x16Eq:
+ case Kind::kI8x16Ne:
+ case Kind::kI8x16GtS:
+ case Kind::kI8x16GtU:
+ case Kind::kI8x16GeS:
+ case Kind::kI8x16GeU:
+ case Kind::kS128And:
+ case Kind::kS128AndNot:
+ case Kind::kS128Or:
+ case Kind::kS128Xor:
+ case Kind::kI8x16Add:
+ case Kind::kI8x16AddSatS:
+ case Kind::kI8x16AddSatU:
+ case Kind::kI8x16Sub:
+ case Kind::kI8x16SubSatS:
+ case Kind::kI8x16SubSatU:
+ case Kind::kI8x16MinS:
+ case Kind::kI8x16MinU:
+ case Kind::kI8x16MaxS:
+ case Kind::kI8x16MaxU:
+ case Kind::kI8x16RoundingAverageU:
+ case Kind::kI16x8ExtMulLowI8x16S:
+ case Kind::kI16x8ExtMulHighI8x16S:
+ case Kind::kI16x8ExtMulLowI8x16U:
+ case Kind::kI16x8ExtMulHighI8x16U:
+ return MachineRepresentation::kWord8;
+ case Kind::kI16x8Eq:
+ case Kind::kI16x8Ne:
+ case Kind::kI16x8GtS:
+ case Kind::kI16x8GtU:
+ case Kind::kI16x8GeS:
+ case Kind::kI16x8GeU:
+ case Kind::kI8x16SConvertI16x8:
+ case Kind::kI8x16UConvertI16x8:
+ case Kind::kI16x8Q15MulRSatS:
+ case Kind::kI16x8Add:
+ case Kind::kI16x8AddSatS:
+ case Kind::kI16x8AddSatU:
+ case Kind::kI16x8Sub:
+ case Kind::kI16x8SubSatS:
+ case Kind::kI16x8SubSatU:
+ case Kind::kI16x8Mul:
+ case Kind::kI16x8MinS:
+ case Kind::kI16x8MinU:
+ case Kind::kI16x8MaxS:
+ case Kind::kI16x8MaxU:
+ case Kind::kI16x8RoundingAverageU:
+ case Kind::kI16x8RelaxedQ15MulRS:
+ case Kind::kI32x4ExtMulLowI16x8S:
+ case Kind::kI32x4ExtMulHighI16x8S:
+ case Kind::kI32x4ExtMulLowI16x8U:
+ case Kind::kI32x4ExtMulHighI16x8U:
+ return MachineRepresentation::kWord16;
+ case Kind::kI32x4Eq:
+ case Kind::kI32x4Ne:
+ case Kind::kI32x4GtS:
+ case Kind::kI32x4GtU:
+ case Kind::kI32x4GeS:
+ case Kind::kI32x4GeU:
+ case Kind::kI16x8SConvertI32x4:
+ case Kind::kI16x8UConvertI32x4:
+ case Kind::kI32x4Add:
+ case Kind::kI32x4Sub:
+ case Kind::kI32x4Mul:
+ case Kind::kI32x4MinS:
+ case Kind::kI32x4MinU:
+ case Kind::kI32x4MaxS:
+ case Kind::kI32x4MaxU:
+ case Kind::kI64x2ExtMulLowI32x4S:
+ case Kind::kI64x2ExtMulHighI32x4S:
+ case Kind::kI64x2ExtMulLowI32x4U:
+ case Kind::kI64x2ExtMulHighI32x4U:
+ return MachineRepresentation::kWord32;
+ case Kind::kF32x4Eq:
+ case Kind::kF32x4Ne:
+ case Kind::kF32x4Lt:
+ case Kind::kF32x4Le:
+ case Kind::kF32x4Add:
+ case Kind::kF32x4Sub:
+ case Kind::kF32x4Mul:
+ case Kind::kF32x4Div:
+ case Kind::kF32x4Min:
+ case Kind::kF32x4Max:
+ case Kind::kF32x4Pmin:
+ case Kind::kF32x4Pmax:
+ case Kind::kF32x4RelaxedMin:
+ case Kind::kF32x4RelaxedMax:
+ return MachineRepresentation::kFloat32;
+ case Kind::kF16x8Eq:
+ case Kind::kF16x8Ne:
+ case Kind::kF16x8Lt:
+ case Kind::kF16x8Le:
+ case Kind::kF16x8Add:
+ case Kind::kF16x8Sub:
+ case Kind::kF16x8Mul:
+ case Kind::kF16x8Div:
+ case Kind::kF16x8Min:
+ case Kind::kF16x8Max:
+ case Kind::kF16x8Pmin:
+ case Kind::kF16x8Pmax:
+ return MachineRepresentation::kFloat16;
+ case Kind::kI64x2Add:
+ case Kind::kI64x2Sub:
+ case Kind::kI64x2Mul:
+ case Kind::kI64x2Eq:
+ case Kind::kI64x2Ne:
+ case Kind::kI64x2GtS:
+ case Kind::kI64x2GeS:
+ return MachineRepresentation::kWord64;
+ case Kind::kF64x2Eq:
+ case Kind::kF64x2Ne:
+ case Kind::kF64x2Lt:
+ case Kind::kF64x2Le:
+ case Kind::kF64x2Add:
+ case Kind::kF64x2Sub:
+ case Kind::kF64x2Mul:
+ case Kind::kF64x2Div:
+ case Kind::kF64x2Min:
+ case Kind::kF64x2Max:
+ case Kind::kF64x2Pmin:
+ case Kind::kF64x2Pmax:
+ case Kind::kF64x2RelaxedMin:
+ case Kind::kF64x2RelaxedMax:
+ return MachineRepresentation::kFloat64;
+ }
+ }
+
+ MachineRepresentation input_element_rep() const {
+ return input_element_rep(kind);
+ }
auto options() const { return std::tuple{kind}; }
};
@@ -8992,6 +9299,168 @@ struct Simd128UnaryOp : FixedArityOperationT<1, Simd128UnaryOp> {
Kind kind;
+ static MachineRepresentation InputElementRep(Kind kind) {
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kS128Not:
+ case Kind::kI8x16Abs:
+ case Kind::kI8x16Neg:
+ case Kind::kI8x16Popcnt:
+ case Kind::kI16x8SConvertI8x16Low:
+ case Kind::kI16x8SConvertI8x16High:
+ case Kind::kI16x8UConvertI8x16Low:
+ case Kind::kI16x8UConvertI8x16High:
+ case Kind::kI16x8ExtAddPairwiseI8x16S:
+ case Kind::kI16x8ExtAddPairwiseI8x16U:
+ case Kind::kSimd128ReverseBytes:
+ return MachineRepresentation::kWord8;
+ case Kind::kI16x8Abs:
+ case Kind::kI16x8Neg:
+ case Kind::kI32x4SConvertI16x8Low:
+ case Kind::kI32x4SConvertI16x8High:
+ case Kind::kI32x4UConvertI16x8Low:
+ case Kind::kI32x4UConvertI16x8High:
+ case Kind::kI32x4ExtAddPairwiseI16x8S:
+ case Kind::kI32x4ExtAddPairwiseI16x8U:
+ case Kind::kF16x8SConvertI16x8:
+ case Kind::kF16x8UConvertI16x8:
+ return MachineRepresentation::kWord16;
+ case Kind::kI32x4Abs:
+ case Kind::kI32x4Neg:
+ case Kind::kF32x4SConvertI32x4:
+ case Kind::kF32x4UConvertI32x4:
+ case Kind::kI64x2SConvertI32x4Low:
+ case Kind::kI64x2SConvertI32x4High:
+ case Kind::kI64x2UConvertI32x4Low:
+ case Kind::kI64x2UConvertI32x4High:
+ case Kind::kF64x2ConvertLowI32x4S:
+ case Kind::kF64x2ConvertLowI32x4U:
+ return MachineRepresentation::kWord32;
+ case Kind::kF32x4Abs:
+ case Kind::kF32x4Neg:
+ case Kind::kF32x4Sqrt:
+ case Kind::kI32x4SConvertF32x4:
+ case Kind::kI32x4UConvertF32x4:
+ case Kind::kI32x4RelaxedTruncF32x4S:
+ case Kind::kI32x4RelaxedTruncF32x4U:
+ case Kind::kF32x4Ceil:
+ case Kind::kF32x4Floor:
+ case Kind::kF32x4Trunc:
+ case Kind::kF32x4NearestInt:
+ case Kind::kF64x2PromoteLowF32x4:
+ case Kind::kF16x8DemoteF32x4Zero:
+ return MachineRepresentation::kFloat32;
+ case Kind::kF16x8Abs:
+ case Kind::kF16x8Neg:
+ case Kind::kF16x8Sqrt:
+ case Kind::kF16x8Ceil:
+ case Kind::kF16x8Floor:
+ case Kind::kF16x8Trunc:
+ case Kind::kF16x8NearestInt:
+ case Kind::kI16x8SConvertF16x8:
+ case Kind::kI16x8UConvertF16x8:
+ case Kind::kF32x4PromoteLowF16x8:
+ return MachineRepresentation::kFloat16;
+ case Kind::kI64x2Abs:
+ case Kind::kI64x2Neg:
+ return MachineRepresentation::kWord64;
+ case Kind::kF64x2Abs:
+ case Kind::kF64x2Neg:
+ case Kind::kF64x2Sqrt:
+ case Kind::kF64x2Ceil:
+ case Kind::kF64x2Floor:
+ case Kind::kF64x2Trunc:
+ case Kind::kF64x2NearestInt:
+ case Kind::kF32x4DemoteF64x2Zero:
+ case Kind::kI32x4TruncSatF64x2SZero:
+ case Kind::kI32x4TruncSatF64x2UZero:
+ case Kind::kI32x4RelaxedTruncF64x2SZero:
+ case Kind::kI32x4RelaxedTruncF64x2UZero:
+ case Kind::kF16x8DemoteF64x2Zero:
+ return MachineRepresentation::kFloat64;
+ }
+ }
+
+ static bool IsLaneWise(Kind kind) {
+ // Preserve lane count and operate on corresponding lanes independently.
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI16x8SConvertI8x16Low:
+ case Kind::kI16x8SConvertI8x16High:
+ case Kind::kI16x8UConvertI8x16Low:
+ case Kind::kI16x8UConvertI8x16High:
+ case Kind::kI32x4SConvertI16x8Low:
+ case Kind::kI32x4SConvertI16x8High:
+ case Kind::kI32x4UConvertI16x8Low:
+ case Kind::kI32x4UConvertI16x8High:
+ case Kind::kI64x2SConvertI32x4Low:
+ case Kind::kI64x2SConvertI32x4High:
+ case Kind::kI64x2UConvertI32x4Low:
+ case Kind::kI64x2UConvertI32x4High:
+ case Kind::kI16x8ExtAddPairwiseI8x16S:
+ case Kind::kI16x8ExtAddPairwiseI8x16U:
+ case Kind::kI32x4ExtAddPairwiseI16x8S:
+ case Kind::kI32x4ExtAddPairwiseI16x8U:
+ case Kind::kF32x4DemoteF64x2Zero:
+ case Kind::kF64x2PromoteLowF32x4:
+ case Kind::kI32x4TruncSatF64x2SZero:
+ case Kind::kI32x4TruncSatF64x2UZero:
+ case Kind::kF64x2ConvertLowI32x4S:
+ case Kind::kF64x2ConvertLowI32x4U:
+ case Kind::kI32x4RelaxedTruncF64x2SZero:
+ case Kind::kI32x4RelaxedTruncF64x2UZero:
+ case Kind::kF16x8DemoteF32x4Zero:
+ case Kind::kF16x8DemoteF64x2Zero:
+ case Kind::kF32x4PromoteLowF16x8:
+ case Kind::kSimd128ReverseBytes:
+ return false;
+ case Kind::kS128Not:
+ case Kind::kI8x16Abs:
+ case Kind::kI8x16Neg:
+ case Kind::kI8x16Popcnt:
+ case Kind::kI16x8Abs:
+ case Kind::kI16x8Neg:
+ case Kind::kI32x4Abs:
+ case Kind::kI32x4Neg:
+ case Kind::kI64x2Abs:
+ case Kind::kI64x2Neg:
+ case Kind::kF32x4Abs:
+ case Kind::kF32x4Neg:
+ case Kind::kF32x4Sqrt:
+ case Kind::kF64x2Abs:
+ case Kind::kF64x2Neg:
+ case Kind::kF64x2Sqrt:
+ case Kind::kI32x4SConvertF32x4:
+ case Kind::kI32x4UConvertF32x4:
+ case Kind::kF32x4SConvertI32x4:
+ case Kind::kF32x4UConvertI32x4:
+ case Kind::kI32x4RelaxedTruncF32x4S:
+ case Kind::kI32x4RelaxedTruncF32x4U:
+ case Kind::kF16x8Abs:
+ case Kind::kF16x8Neg:
+ case Kind::kF16x8Sqrt:
+ case Kind::kF16x8Ceil:
+ case Kind::kF16x8Floor:
+ case Kind::kF16x8Trunc:
+ case Kind::kF16x8NearestInt:
+ case Kind::kI16x8SConvertF16x8:
+ case Kind::kI16x8UConvertF16x8:
+ case Kind::kF16x8SConvertI16x8:
+ case Kind::kF16x8UConvertI16x8:
+ case Kind::kF32x4Ceil:
+ case Kind::kF32x4Floor:
+ case Kind::kF32x4Trunc:
+ case Kind::kF32x4NearestInt:
+ case Kind::kF64x2Ceil:
+ case Kind::kF64x2Floor:
+ case Kind::kF64x2Trunc:
+ case Kind::kF64x2NearestInt:
+ return true;
+ }
+ }
+
static constexpr OpEffects effects = OpEffects();
base::Vector<const RegisterRepresentation> outputs_rep() const {
@@ -9007,6 +9476,9 @@ struct Simd128UnaryOp : FixedArityOperationT<1, Simd128UnaryOp> {
V<Simd128> input() const { return Base::input<Simd128>(0); }
+ MachineRepresentation input_element_rep() const {
+ return InputElementRep(kind);
+ }
auto options() const { return std::tuple{kind}; }
};
@@ -9076,6 +9548,50 @@ struct Simd128ShiftOp : FixedArityOperationT<2, Simd128ShiftOp> {
static constexpr OpEffects effects = OpEffects();
+ static MachineRepresentation InputElementRep(Kind kind) {
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI8x16Shl:
+ case Kind::kI8x16ShrS:
+ case Kind::kI8x16ShrU:
+ return MachineRepresentation::kWord8;
+ case Kind::kI16x8Shl:
+ case Kind::kI16x8ShrS:
+ case Kind::kI16x8ShrU:
+ return MachineRepresentation::kWord16;
+ case Kind::kI32x4Shl:
+ case Kind::kI32x4ShrS:
+ case Kind::kI32x4ShrU:
+ return MachineRepresentation::kWord32;
+ case Kind::kI64x2Shl:
+ case Kind::kI64x2ShrS:
+ case Kind::kI64x2ShrU:
+ return MachineRepresentation::kWord64;
+ }
+ }
+
+ static bool IsLaneWise(Kind kind) {
+ // Preserve lane count and operate on corresponding lanes independently.
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI8x16Shl:
+ case Kind::kI8x16ShrS:
+ case Kind::kI8x16ShrU:
+ case Kind::kI16x8Shl:
+ case Kind::kI16x8ShrS:
+ case Kind::kI16x8ShrU:
+ case Kind::kI32x4Shl:
+ case Kind::kI32x4ShrS:
+ case Kind::kI32x4ShrU:
+ case Kind::kI64x2Shl:
+ case Kind::kI64x2ShrS:
+ case Kind::kI64x2ShrU:
+ return true;
+ }
+ }
+
base::Vector<const RegisterRepresentation> outputs_rep() const {
return RepVector<RegisterRepresentation::Simd128()>();
}
@@ -9092,6 +9608,9 @@ struct Simd128ShiftOp : FixedArityOperationT<2, Simd128ShiftOp> {
V<Simd128> input() const { return Base::input<Simd128>(0); }
V<Word32> shift() const { return Base::input<Word32>(1); }
+ MachineRepresentation input_element_rep() const {
+ return InputElementRep(kind);
+ }
auto options() const { return std::tuple{kind}; }
};
@@ -9225,6 +9744,53 @@ struct Simd128TernaryOp : FixedArityOperationT<3, Simd128TernaryOp> {
Kind kind;
+ static bool IsLaneWise(Kind kind) {
+ // Preserve lane count and operate on corresponding lanes independently.
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kI32x4DotI8x16I7x16AddS:
+ return false;
+ case Kind::kS128Select:
+ case Kind::kI8x16RelaxedLaneSelect:
+ case Kind::kI16x8RelaxedLaneSelect:
+ case Kind::kI32x4RelaxedLaneSelect:
+ case Kind::kI64x2RelaxedLaneSelect:
+ case Kind::kF32x4Qfma:
+ case Kind::kF32x4Qfms:
+ case Kind::kF64x2Qfma:
+ case Kind::kF64x2Qfms:
+ case Kind::kF16x8Qfma:
+ case Kind::kF16x8Qfms:
+ return true;
+ }
+ }
+
+ static MachineRepresentation InputElementRep(Kind kind) {
+ switch (kind) {
+ default:
+ UNREACHABLE();
+ case Kind::kS128Select:
+ case Kind::kI8x16RelaxedLaneSelect:
+ return MachineRepresentation::kWord8;
+ case Kind::kI16x8RelaxedLaneSelect:
+ return MachineRepresentation::kWord16;
+ case Kind::kI32x4RelaxedLaneSelect:
+ return MachineRepresentation::kWord32;
+ case Kind::kF32x4Qfma:
+ case Kind::kF32x4Qfms:
+ return MachineRepresentation::kFloat32;
+ case Kind::kI64x2RelaxedLaneSelect:
+ return MachineRepresentation::kWord64;
+ case Kind::kF64x2Qfma:
+ case Kind::kF64x2Qfms:
+ return MachineRepresentation::kFloat64;
+ case Kind::kF16x8Qfma:
+ case Kind::kF16x8Qfms:
+ return MachineRepresentation::kFloat16;
+ }
+ }
+
static constexpr OpEffects effects = OpEffects();
base::Vector<const RegisterRepresentation> outputs_rep() const {
@@ -9246,6 +9812,9 @@ struct Simd128TernaryOp : FixedArityOperationT<3, Simd128TernaryOp> {
V<Simd128> second() const { return input<Simd128>(1); }
V<Simd128> third() const { return input<Simd128>(2); }
+ MachineRepresentation input_element_rep() const {
+ return InputElementRep(kind);
+ }
auto options() const { return std::tuple{kind}; }
};
@@ -9661,7 +10230,7 @@ struct Simd128ShuffleOp : FixedArityOperationT<2, Simd128ShuffleOp> {
kI8x16,
};
- uint8_t shuffle[kSimd128Size] = {0};
+ std::array<uint8_t, kSimd128Size> shuffle = {0};
const Kind kind;
static constexpr OpEffects effects = OpEffects();
@@ -9699,9 +10268,13 @@ struct Simd128ShuffleOp : FixedArityOperationT<2, Simd128ShuffleOp> {
count = 16;
break;
}
- std::copy_n(incoming_shuffle, count, shuffle);
+ std::copy_n(incoming_shuffle, count, shuffle.begin());
}
+ Simd128ShuffleOp(V<Simd128> left, V<Simd128> right, Kind kind,
+ const std::array<uint8_t, kSimd128Size>& incoming_shuffle)
+ : Base(left, right), shuffle(incoming_shuffle), kind(kind) {}
+
V<Simd128> left() const { return input<Simd128>(0); }
V<Simd128> right() const { return input<Simd128>(1); }
@@ -9715,16 +10288,6 @@ struct Simd128ShuffleOp : FixedArityOperationT<2, Simd128ShuffleOp> {
}
auto options() const { return std::tuple{kind, shuffle}; }
- // {options()} decays {shuffle} to a pointer, so the inherited {operator==}
- // and {hash_value} would compare addresses.
- bool operator==(const Simd128ShuffleOp& other) const {
- return inputs() == other.inputs() && kind == other.kind &&
- std::memcmp(shuffle, other.shuffle, kSimd128Size) == 0;
- }
- size_t hash_value(
- HashingStrategy strategy = HashingStrategy::kDefault) const {
- return HashWithOptions(kind, base::VectorOf(shuffle));
- }
void PrintOptions(std::ostream& os) const;
};
@@ -9795,14 +10358,17 @@ struct Simd128LoadPairDeinterleaveOp
struct Simd256ConstantOp : FixedArityOperationT<0, Simd256ConstantOp> {
static constexpr uint8_t kZero[kSimd256Size] = {};
- uint8_t value[kSimd256Size];
+ std::array<uint8_t, kSimd256Size> value;
static constexpr OpEffects effects = OpEffects();
explicit Simd256ConstantOp(const uint8_t incoming_value[kSimd256Size])
: Base() {
- std::copy(incoming_value, incoming_value + kSimd256Size, value);
+ std::copy(incoming_value, incoming_value + kSimd256Size, value.begin());
}
+ explicit Simd256ConstantOp(
+ const std::array<uint8_t, kSimd256Size>& incoming_value)
+ : Base(), value(incoming_value) {}
base::Vector<const RegisterRepresentation> outputs_rep() const {
return RepVector<RegisterRepresentation::Simd256()>();
@@ -9817,18 +10383,11 @@ struct Simd256ConstantOp : FixedArityOperationT<0, Simd256ConstantOp> {
// TODO(14108): Validate.
}
- bool IsZero() const { return std::memcmp(kZero, value, kSimd256Size) == 0; }
+ bool IsZero() const {
+ return std::memcmp(kZero, value.data(), kSimd256Size) == 0;
+ }
auto options() const { return std::tuple{value}; }
- // {options()} decays {value} to a pointer, so the inherited {operator==} and
- // {hash_value} would compare addresses.
- bool operator==(const Simd256ConstantOp& other) const {
- return std::memcmp(value, other.value, kSimd256Size) == 0;
- }
- size_t hash_value(
- HashingStrategy strategy = HashingStrategy::kDefault) const {
- return HashWithOptions(base::VectorOf(value));
- }
void PrintOptions(std::ostream& os) const;
};
diff --git a/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc b/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
index 8ef949f7a30..a6e00c86105 100644
--- a/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
+++ b/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
@@ -1481,6 +1481,13 @@ class GraphBuildingNodeProcessor {
return nullptr;
}
+ SBXCHECK_EQ(node->expected_parameter_count(), JSParameterCount(wasm_arity));
+ // WasmInJSInliningReducer requires every argument to be wrapped in a
+ // ProcessWasmArgument node to provide the caller's eager deopt FrameState.
+ for (int i = 0; i < wasm_arity; ++i) {
+ SBXCHECK(node->arg(i).node()->Is<maglev::ProcessWasmArgument>());
+ }
+
if (!__ data()->TrySetWasmInstanceForInlining(native_module->module(),
instance_handle)) {
TRACE_WASM_INLINING(
@@ -1542,8 +1549,8 @@ class GraphBuildingNodeProcessor {
JSWasmCallParameters* wasm_call_params = nullptr;
#if V8_ENABLE_WEBASSEMBLY
SharedFunctionInfoRef shared = node->shared_function_info();
- Tagged<Code> code = shared.object()->GetCode(isolate_);
- Tagged<Object> data = shared.object()->GetTrustedData(isolate_);
+ Tagged<Code> code =
+ isolate_->js_dispatch_table().GetCode(node->dispatch_handle());
// If the code is a JS-to-Wasm wrapper (either the generic builtin or a
// compiled wrapper), we might be able to inline it.
bool is_calling_js_to_wasm_wrapper_builtin =
@@ -1552,7 +1559,7 @@ class GraphBuildingNodeProcessor {
if (v8_flags.wasm_in_js_inlining_wrapper &&
is_calling_js_to_wasm_wrapper_builtin) {
Tagged<WasmExportedFunctionData> function_data;
- if (TryCast(TrustedCast<TrustedObject>(data), &function_data)) {
+ if (TryCast(shared.object()->GetTrustedData(isolate_), &function_data)) {
Tagged<WasmTrustedInstanceData> instance_data =
function_data->instance_data();
wasm::NativeModule* native_module = instance_data->native_module();
@@ -1846,11 +1853,11 @@ class GraphBuildingNodeProcessor {
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::ThrowReferenceErrorIfHole* node,
+ maglev::ProcessResult Process(maglev::ThrowReferenceErrorIfTdzHole* node,
const maglev::ProcessingState& state) {
ThrowingScope throwing_scope(this, node);
- IF (UNLIKELY(RootEqual(node->ValueInput(), RootIndex::kTheHoleValue))) {
+ IF (UNLIKELY(RootEqual(node->ValueInput(), RootIndex::kTdzHoleValue))) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->lazy_deopt_info());
__ template CallRuntime<runtime::ThrowAccessedUninitializedVariable>(
frame_state, native_context(),
@@ -1892,12 +1899,13 @@ class GraphBuildingNodeProcessor {
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::ThrowSuperAlreadyCalledIfNotHole* node,
- const maglev::ProcessingState& state) {
+ maglev::ProcessResult Process(
+ maglev::ThrowSuperAlreadyCalledIfNotTdzHole* node,
+ const maglev::ProcessingState& state) {
ThrowingScope throwing_scope(this, node);
IF_NOT (LIKELY(__ RootEqual(Map(node->ValueInput()),
- RootIndex::kTheHoleValue, isolate_))) {
+ RootIndex::kTdzHoleValue, isolate_))) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->lazy_deopt_info());
__ template CallRuntime<runtime::ThrowSuperAlreadyCalledError>(
frame_state, native_context(), {}, ShouldLazyDeoptOnThrow(node));
@@ -1911,11 +1919,11 @@ class GraphBuildingNodeProcessor {
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::ThrowSuperNotCalledIfHole* node,
+ maglev::ProcessResult Process(maglev::ThrowSuperNotCalledIfTdzHole* node,
const maglev::ProcessingState& state) {
ThrowingScope throwing_scope(this, node);
- IF (UNLIKELY(__ RootEqual(Map(node->ValueInput()), RootIndex::kTheHoleValue,
+ IF (UNLIKELY(__ RootEqual(Map(node->ValueInput()), RootIndex::kTdzHoleValue,
isolate_))) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->lazy_deopt_info());
__ template CallRuntime<runtime::ThrowSuperNotCalled>(
@@ -3542,6 +3550,17 @@ class GraphBuildingNodeProcessor {
}
return MemoryRepresentation::AnyTagged();
}
+ // Write barrier kind for tagged stores for which Maglev already established
+ // that no write barrier is needed. With write barrier verification enabled,
+ // such stores are marked as "skipped" rather than as "no barrier", which
+ // makes the backend emit a runtime check.
+ WriteBarrierKind ElidedWriteBarrierKind(MemoryRepresentation mem_repr) {
+ if (!v8_flags.verify_write_barriers ||
+ mem_repr == MemoryRepresentation::TaggedSigned()) {
+ return WriteBarrierKind::kNoWriteBarrier;
+ }
+ return WriteBarrierKind::kSkippedWriteBarrier;
+ }
WriteBarrierKind WriteBarrierKindFor(MemoryRepresentation mem_repr) {
if (mem_repr == MemoryRepresentation::TaggedSigned()) {
return WriteBarrierKind::kNoWriteBarrier;
@@ -3554,11 +3573,11 @@ class GraphBuildingNodeProcessor {
}
maglev::ProcessResult Process(maglev::StoreTaggedFieldNoWriteBarrier* node,
const maglev::ProcessingState& state) {
+ MemoryRepresentation mem_repr = TaggedMemoryRepresentation(
+ node->ValueInput().node()->GetStaticType(broker_));
__ Store(Map(node->ObjectInput()), Map(node->ValueInput()),
- StoreOp::Kind::TaggedBase(),
- TaggedMemoryRepresentation(
- node->ValueInput().node()->GetStaticType(broker_)),
- WriteBarrierKind::kNoWriteBarrier, node->offset(),
+ StoreOp::Kind::TaggedBase(), mem_repr,
+ ElidedWriteBarrierKind(mem_repr), node->offset(),
node->initializing_or_transitioning());
return maglev::ProcessResult::kContinue;
}
@@ -3603,7 +3622,8 @@ class GraphBuildingNodeProcessor {
const maglev::ProcessingState& state) {
__ Store(Map(node->CellInput()), Map(node->ValueInput()),
StoreOp::Kind::TaggedBase(), MemoryRepresentation::AnyTagged(),
- WriteBarrierKind::kNoWriteBarrier, node->offset(), false);
+ ElidedWriteBarrierKind(MemoryRepresentation::AnyTagged()),
+ node->offset(), false);
return maglev::ProcessResult::kContinue;
}
maglev::ProcessResult Process(maglev::StoreInt32ContextCell* node,
@@ -3633,10 +3653,11 @@ class GraphBuildingNodeProcessor {
maglev::ProcessResult Process(
maglev::StoreFixedArrayElementNoWriteBarrier* node,
const maglev::ProcessingState& state) {
- __ StoreFixedArrayElement(Map(node->ElementsInput()),
- __ ChangeInt32ToIntPtr(Map(node->IndexInput())),
- Map(node->ValueInput()),
- WriteBarrierKind::kNoWriteBarrier);
+ __ StoreFixedArrayElement(
+ Map(node->ElementsInput()),
+ __ ChangeInt32ToIntPtr(Map(node->IndexInput())),
+ Map(node->ValueInput()),
+ ElidedWriteBarrierKind(MemoryRepresentation::AnyTagged()));
return maglev::ProcessResult::kContinue;
}
maglev::ProcessResult Process(
diff --git a/deps/v8/src/compiler/turboshaft/typer.h b/deps/v8/src/compiler/turboshaft/typer.h
index d27a2d92fc1..e83c0562c81 100644
--- a/deps/v8/src/compiler/turboshaft/typer.h
+++ b/deps/v8/src/compiler/turboshaft/typer.h
@@ -12,6 +12,7 @@
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/types.h"
+#include "src/numbers/ieee754.h"
namespace v8::internal::compiler::turboshaft {
@@ -935,7 +936,10 @@ struct FloatOperationTyper {
l.special_values();
// If both sides are decently small sets, we produce the product set.
- auto combine = [](float_t a, float_t b) { return std::pow(a, b); };
+ // Use the same pow implementation as the runtime and constant folding.
+ auto combine = [](float_t a, float_t b) {
+ return static_cast<float_t>(math::pow(a, b));
+ };
if (l.is_set() && r.is_set()) {
auto result = ProductSet(l, r, special_values, zone, combine);
if (!result.IsInvalid()) return result;
diff --git a/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc b/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
index 27ba1c318dd..81f9b29529c 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.cc
@@ -312,11 +312,23 @@ void WasmGCTypeAnalyzer::ProcessStructGet(const StructGetOp& struct_get) {
RefineTypeKnowledgeNotNull(struct_get.object(), struct_get);
input_type_map_[graph_.Index(struct_get)] = type;
wasm::ValueType new_type;
- if (struct_get.is_get_desc()) {
+ if (type.is_uninhabited()) {
+ new_type = wasm::kWasmBottom;
+ } else if (struct_get.is_get_desc()) {
// Descriptor load.
const wasm::TypeDefinition& type_def = module_->type(struct_get.type_index);
DCHECK(type_def.has_descriptor());
- new_type = wasm::ValueType::Ref(module_->heap_type(type_def.descriptor));
+ // Exactness is only propagated if the actual type of the struct
+ // exactly matches the type immediate.
+ wasm::Exactness exactness = type.exactness();
+ if (type.is_none_or_bottom()) {
+ // Subsumption dictates that get_desc(none) <: get_desc(exact $s).
+ exactness = wasm::kExact;
+ } else if (type.has_index() && type.ref_index() != struct_get.type_index) {
+ exactness = wasm::kAnySubtype;
+ }
+ new_type = wasm::ValueType::Ref(module_->heap_type(type_def.descriptor))
+ .AsExact(exactness);
} else {
// Regular field load.
new_type = struct_get.type->field(struct_get.field_index).Unpacked();
@@ -356,18 +368,22 @@ void WasmGCTypeAnalyzer::ProcessGlobalGet(const GlobalGetOp& global_get) {
void WasmGCTypeAnalyzer::ProcessRefFunc(const WasmRefFuncOp& ref_func) {
wasm::ModuleTypeIndex sig_index =
module_->functions[ref_func.function_index].sig_index;
- RefineTypeKnowledge(graph_.Index(ref_func),
- wasm::ValueType::Ref(module_->heap_type(sig_index)),
- ref_func);
+ wasm::ValueType type = wasm::ValueType::Ref(module_->heap_type(sig_index));
+ if (ref_func.function_index >= module_->num_imported_functions ||
+ module_->functions[ref_func.function_index].exact) {
+ type = type.AsExact();
+ }
+ RefineTypeKnowledge(graph_.Index(ref_func), type, ref_func);
}
void WasmGCTypeAnalyzer::ProcessAllocateArray(
const WasmAllocateArrayOp& allocate_array) {
wasm::ModuleTypeIndex type_index =
graph_.Get(allocate_array.rtt()).Cast<RttCanonOp>().type_index;
- RefineTypeKnowledge(graph_.Index(allocate_array),
- wasm::ValueType::Ref(module_->heap_type(type_index)),
- allocate_array);
+ RefineTypeKnowledge(
+ graph_.Index(allocate_array),
+ wasm::ValueType::Ref(module_->heap_type(type_index)).AsExact(),
+ allocate_array);
}
void WasmGCTypeAnalyzer::ProcessAllocateStruct(
const WasmAllocateStructOp& allocate_struct) {
@@ -473,6 +489,9 @@ void WasmGCTypeAnalyzer::ProcessBranchOnTarget(const BranchOp& branch,
target.index().id(), branch.condition().id(),
OpcodeName(condition.opcode), graph_.Index(branch).id(),
OpcodeName(branch.opcode));
+ RefineTypeKnowledge(check.object(), wasm::kWasmBottom, branch);
+ } else if (check.config.to.is_nullable()) {
+ RefineTypeKnowledgeNotNull(check.object(), branch);
}
}
} break;
@@ -489,6 +508,7 @@ void WasmGCTypeAnalyzer::ProcessBranchOnTarget(const BranchOp& branch,
target.index().id(), branch.condition().id(),
OpcodeName(condition.opcode), graph_.Index(branch).id(),
OpcodeName(branch.opcode));
+ RefineTypeKnowledge(is_null.object(), wasm::kWasmBottom, branch);
return;
}
RefineTypeKnowledge(is_null.object(),
diff --git a/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
index 8c9b14f3a0c..2d11e907afc 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-gc-typed-optimization-reducer.h
@@ -253,6 +253,11 @@ class WasmGCTypedOptimizationReducer : public Next {
if (ShouldSkipOptimizationStep()) goto no_change;
wasm::ValueType type = analyzer_.GetInputTypeOrSentinelType(op_idx);
+ // The static information should also be known to the analyzer. If this is
+ // not the case, it indicates that the input operation was not properly
+ // typed.
+ DCHECK(wasm::IsSubtypeOf(type, cast_op.config.from, module_));
+
AssertType(cast_op.object(), type);
if (type.is_uninhabited()) {
// We are either already in unreachable code (then this instruction isn't
@@ -330,6 +335,11 @@ class WasmGCTypedOptimizationReducer : public Next {
if (ShouldSkipOptimizationStep()) goto no_change;
wasm::ValueType type = analyzer_.GetInputTypeOrSentinelType(op_idx);
+ // The static information should also be known to the analyzer. If this is
+ // not the case, it indicates that the input operation was not properly
+ // typed.
+ DCHECK(wasm::IsSubtypeOf(type, type_check.config.from, module_));
+
AssertType(type_check.object(), type);
if (type.is_uninhabited()) {
__ Unreachable();
diff --git a/deps/v8/src/compiler/turboshaft/wasm-in-js-inlining-reducer-inl.h b/deps/v8/src/compiler/turboshaft/wasm-in-js-inlining-reducer-inl.h
index 6ec07fc6220..d582fe36405 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-in-js-inlining-reducer-inl.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-in-js-inlining-reducer-inl.h
@@ -145,6 +145,7 @@ class WasmInJSInliningReducer : public Next {
// guards that eagerly deopt if we fall off the conversion fastpath, e.g.,
// not Smi or HeapNumber. In particular, we do not call builtins that
// could transitively cause a lazy deopt via valueOf/Symbol.toPrimitive.
+ CHECK_IMPLIES(sig->parameter_count() > 0, caller_frame_state.has_value());
V<Any> result = builder.BuildJSToWasmWrapper(
js_closure, js_context, arguments, continuation_frame_state,
descriptor->lazy_deopt_on_throw, caller_frame_state);
@@ -872,6 +873,7 @@ class WasmInJsInliningInterface {
BAILOUT_WASM_OP(StructAtomicRMW)
BAILOUT_WASM_OP(StructAtomicCompareExchange)
BAILOUT_WASM_OP(StructWait)
+ BAILOUT_WASM_OP(ArrayWait)
BAILOUT_WASM_OP(WaitqueueNotify)
BAILOUT_WASM_OP(WaitqueueNew)
diff --git a/deps/v8/src/compiler/turboshaft/wasm-load-elimination-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-load-elimination-reducer.h
index 20f2ebbb3ba..5b620c67013 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-load-elimination-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-load-elimination-reducer.h
@@ -528,12 +528,84 @@ class V8_EXPORT_PRIVATE WasmLoadEliminationReducer : public Next {
Next::Analyze();
}
-#define EMIT_OP(Name) \
+#if DEBUG
+ void EmitReportLoadEliminationError() {
+ CHECK(v8_flags.turboshaft_verify_load_elimination);
+ if (__ data()->pipeline_kind() == TurboshaftPipelineKind::kWasm) {
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kAbort,
+ {__ TagSmi(static_cast<int>(
+ AbortReason::kTurboshaftLoadEliminationError))},
+ __ NoContextConstant());
+ } else {
+ __ template CallRuntime<runtime::Abort>(
+ __ NoContextConstant(),
+ {.messageOrMessageId = __ SmiConstant(
+ Smi::FromEnum(AbortReason::kTurboshaftLoadEliminationError))});
+ }
+ __ Unreachable();
+ }
+
+ void VerifySingleReplacement(OpIndex actual_idx, OpIndex replacement) {
+ RegisterRepresentation actual_rep =
+ __ output_graph().Get(actual_idx).outputs_rep()[0];
+ RegisterRepresentation replacement_rep =
+ __ output_graph().Get(replacement).outputs_rep()[0];
+
+ if (actual_rep == RegisterRepresentation::Simd128()) {
+ // TODO(dmercadier): Implement along with support in LLE.
+ return;
+ }
+
+ // No WLE support is implemented for mismatched (e.g. truncated)
+ // representations.
+ DCHECK_EQ(actual_rep, replacement_rep);
+ IF_NOT (__ Equal(actual_idx, replacement, actual_rep)) {
+ if (actual_rep == any_of(RegisterRepresentation::Float32(),
+ RegisterRepresentation::Float64())) {
+ // Equality might have returned false because both values are NaN.
+ IF (__ Word32BitwiseOr(
+ __ Equal(actual_idx, actual_idx, actual_rep),
+ __ Equal(replacement, replacement, replacement_rep))) {
+ // At least one of {actual_idx} and {replacement} is not NaN.
+ EmitReportLoadEliminationError();
+ }
+ } else {
+ EmitReportLoadEliminationError();
+ }
+ }
+ }
+
+ void VerifyReplacement(OpIndex actual_idx, OpIndex replacement) {
+ if (const MakeTupleOp* actual_tuple =
+ __ output_graph().Get(actual_idx).template TryCast<MakeTupleOp>()) {
+ const MakeTupleOp& replacement_tuple =
+ __ output_graph().Get(replacement).template Cast<MakeTupleOp>();
+ DCHECK_EQ(actual_tuple->input_count, replacement_tuple.input_count);
+ for (int i = 0; i < actual_tuple->input_count; ++i) {
+ VerifySingleReplacement(actual_tuple->input(i),
+ replacement_tuple.input(i));
+ }
+ return;
+ }
+ VerifySingleReplacement(actual_idx, replacement);
+ }
+
+#define VERIFY(Name, ig_index, op, replacement) \
+ if (v8_flags.turboshaft_verify_load_elimination) { \
+ OpIndex actual_idx = Next::ReduceInputGraph##Name(ig_index, op); \
+ VerifyReplacement(actual_idx, replacement); \
+ }
+#else
+#define VERIFY(Name, ig_index, op, replacement)
+#endif // DEBUG
+
+#define EMIT_OP(Name) /* force 80 cols*/ \
OpIndex REDUCE_INPUT_GRAPH(Name)(OpIndex ig_index, const Name##Op& op) { \
if (v8_flags.turboshaft_wasm_load_elimination) { \
OpIndex ig_replacement_index = analyzer_.Replacement(ig_index); \
if (ig_replacement_index.valid()) { \
OpIndex replacement = Asm().MapToNewGraph(ig_replacement_index); \
+ VERIFY(Name, ig_index, op, replacement) \
return replacement; \
} \
} \
@@ -552,6 +624,7 @@ class V8_EXPORT_PRIVATE WasmLoadEliminationReducer : public Next {
OpIndex ig_replacement_index = analyzer_.Replacement(ig_index);
if (ig_replacement_index.valid()) {
OpIndex replacement = Asm().MapToNewGraph(ig_replacement_index);
+ VERIFY(StructGet, ig_index, op, replacement)
return replacement;
}
}
diff --git a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
index 26b861af332..3ec9534bd35 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
@@ -1394,8 +1394,8 @@ PackNode* SLPTree::BuildTreeRec(const NodeGroup& node_group,
DCHECK(op0.Effects() == OpEffects());
// We pack shuffles only if it can match specific patterns. We should
// avoid packing general shuffles because it will cause regression.
- const auto& shuffle0 = shuffle_op0.shuffle;
- const auto& shuffle1 = shuffle_op1.shuffle;
+ const uint8_t* shuffle0 = shuffle_op0.shuffle.data();
+ const uint8_t* shuffle1 = shuffle_op1.shuffle.data();
if (CompareCharsEqual(shuffle0, shuffle1, kSimd128Size)) {
if (IsSplat(node_group)) {
diff --git a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
index dbe9a0b0ae7..e4dbd2bf091 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
@@ -788,8 +788,8 @@ class WasmRevecReducer : public UniformReducerAdapter<WasmRevecReducer, Next> {
const Simd128ConstantOp& op1 =
__ input_graph().Get(inputs[1]).template Cast<Simd128ConstantOp>();
uint8_t value[kSimd256Size];
- memcpy(value, op0.value, kSimd128Size);
- memcpy(value + kSimd128Size, op1.value, kSimd128Size);
+ memcpy(value, op0.value.data(), kSimd128Size);
+ memcpy(value + kSimd128Size, op1.value.data(), kSimd128Size);
og_index = __ Simd256Constant(value);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
index f21c0cd6e76..5938a6dd34a 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
@@ -26,45 +26,56 @@ namespace v8::internal::compiler::turboshaft {
s[11], s[12], s[13], s[14], s[15]); \
} while (false)
-void DemandedByteAnalysis::Add(OpIndex node, DemandedBytes demanded) {
+void DemandedByteAnalysis::Add(OpIndex node, DemandState demand) {
const Operation& op = input_graph().Get(node);
// We're trying to find out which SIMD bytes of op are used. If op has more
// than a single user we will have to visit it multiple times. Both `Record`
// methods will attempt to recursively add more operations.
if (op.saturated_use_count.Is(1)) {
- TRACE("Found Op %d, demanded bytes: %#04x\n", input_graph().Index(op).id(),
- static_cast<uint32_t>(demanded.bytes()));
- RecordOp(op, demanded);
+ RecordOp(op, demand);
} else {
- RecordPartialOp(op, demanded);
+ RecordPartialOp(op, demand);
}
}
void DemandedByteAnalysis::AddOp(const Simd128UnaryOp& unop,
- DemandedBytes demanded) {
+ DemandState demand) {
if (Visited(&unop)) return;
visited_.insert(&unop);
if (IsUnaryLowHalfOp(unop.kind)) {
- demanded.HalveWithLimit(GetInputElementSizeInBytes(unop.kind));
- Add(unop.input(), demanded);
+ demand.bytes.HalveWithLimit(ElementSizeInBytes(unop.input_element_rep()));
+ Add(unop.input(), demand);
+ } else if (IsUnaryPassThruOp(unop.kind)) {
+ if (!TrySearchThroughPassThru(
+ unop, demand, ElementSizeInBytes(unop.input_element_rep()))) {
+ return;
+ }
+ Add(unop.input(), demand);
}
}
void DemandedByteAnalysis::AddOp(const Simd128BinopOp& binop,
- DemandedBytes demanded) {
+ DemandState demand) {
if (Visited(&binop)) return;
visited_.insert(&binop);
if (IsBinaryLowHalfOp(binop.kind)) {
- demanded.HalveWithLimit(GetInputElementSizeInBytes(binop.kind));
- Add(binop.left(), demanded);
- Add(binop.right(), demanded);
+ demand.bytes.HalveWithLimit(ElementSizeInBytes(binop.input_element_rep()));
+ Add(binop.left(), demand);
+ Add(binop.right(), demand);
+ } else if (IsBinaryPassThruOp(binop.kind)) {
+ if (!TrySearchThroughPassThru(
+ binop, demand, ElementSizeInBytes(binop.input_element_rep()))) {
+ return;
+ }
+ Add(binop.left(), demand);
+ Add(binop.right(), demand);
}
}
void DemandedByteAnalysis::AddOp(const Simd128ExtractLaneOp& extract_op,
- DemandedBytes demanded) {
+ DemandState demand) {
if (Visited(&extract_op)) return;
visited_.insert(&extract_op);
@@ -73,68 +84,107 @@ void DemandedByteAnalysis::AddOp(const Simd128ExtractLaneOp& extract_op,
uint8_t elem_size =
ElementSizeInBytes(Simd128ExtractLaneOp::element_rep(extract_op.kind));
- demanded = DemandedBytes::LowFromLane(elem_size, extract_op.lane);
+ demand.bytes = DemandedBytes::LowFromLane(elem_size, extract_op.lane);
TRACE("ExtractOp %d extracts lane %d, of size %d, so demands: %#04x\n",
input_graph().Index(extract_op).id(), extract_op.lane, elem_size,
- static_cast<uint32_t>(demanded.bytes()));
- Add(extract_op.input(), demanded);
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ Add(extract_op.input(), demand);
}
void DemandedByteAnalysis::AddOp(const Simd128LaneMemoryOp& lane_op,
- DemandedBytes demanded) {
+ DemandState demand) {
if (Visited(&lane_op)) return;
visited_.insert(&lane_op);
if (lane_op.mode == Simd128LaneMemoryOp::Mode::kStore) {
- demanded = DemandedBytes::LowFromLane(lane_op.lane_size(), lane_op.lane);
+ demand.bytes =
+ DemandedBytes::LowFromLane(lane_op.lane_size(), lane_op.lane);
TRACE("LaneMemoryOp %d stores lane %d, of size %d, so demands: %#04x\n",
input_graph().Index(lane_op).id(), lane_op.lane, lane_op.lane_size(),
- static_cast<uint32_t>(demanded.bytes()));
- Add(lane_op.value(), demanded);
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ Add(lane_op.value(), demand);
+ }
+}
+
+void DemandedByteAnalysis::AddOp(const Simd128ShiftOp& shiftop,
+ DemandState demand) {
+ if (Visited(&shiftop)) return;
+ visited_.insert(&shiftop);
+
+ if (IsShiftPassThruOp(shiftop.kind)) {
+ if (!TrySearchThroughPassThru(
+ shiftop, demand, ElementSizeInBytes(shiftop.input_element_rep()))) {
+ return;
+ }
+ Add(shiftop.input(), demand);
+ }
+}
+
+void DemandedByteAnalysis::AddOp(const Simd128TernaryOp& ternary,
+ DemandState demand) {
+ if (Visited(&ternary)) return;
+ visited_.insert(&ternary);
+
+ if (IsTernaryPassThruOp(ternary.kind)) {
+ if (!TrySearchThroughPassThru(
+ ternary, demand, ElementSizeInBytes(ternary.input_element_rep()))) {
+ return;
+ }
+ Add(ternary.first(), demand);
+ Add(ternary.second(), demand);
+ Add(ternary.third(), demand);
}
}
-void DemandedByteAnalysis::RecordOp(const Operation& op,
- DemandedBytes demanded) {
+void DemandedByteAnalysis::RecordOp(const Operation& op, DemandState demand) {
+ // Don't record it if we can't reduce it.
+ if (demand.bytes.IsAll()) return;
+
if (auto* unop = op.TryCast<Simd128UnaryOp>()) {
- AddOp(*unop, demanded);
+ AddOp(*unop, demand);
} else if (auto* binop = op.TryCast<Simd128BinopOp>()) {
- AddOp(*binop, demanded);
+ AddOp(*binop, demand);
+ } else if (auto* shiftop = op.TryCast<Simd128ShiftOp>()) {
+ AddOp(*shiftop, demand);
+ } else if (auto* ternary = op.TryCast<Simd128TernaryOp>()) {
+ AddOp(*ternary, demand);
} else if (auto* extract_op = op.TryCast<Simd128ExtractLaneOp>()) {
- AddOp(*extract_op, demanded);
+ AddOp(*extract_op, demand);
} else if (auto* lane_op = op.TryCast<Simd128LaneMemoryOp>()) {
- AddOp(*lane_op, demanded);
+ AddOp(*lane_op, demand);
} else if (auto* shuffle = op.TryCast<Simd128ShuffleOp>()) {
- if (!demanded.IsAll()) {
- if (demanded_bytes_.size() < kMaxNumOperations) {
- demanded_bytes_.emplace_back(shuffle, demanded);
- } else if (!demanded_limit_reached_) {
- TRACE("Demanded elements limit reached in RecordOp\n");
- demanded_limit_reached_ = true;
- }
+ if (demanded_bytes_.size() < kMaxNumOperations) {
+ TRACE("Shuffle Op %d, demanded bytes: %#04x\n",
+ input_graph().Index(op).id(),
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ demanded_bytes_.emplace_back(shuffle, demand.bytes);
+ } else if (!demanded_limit_reached_) {
+ TRACE("Demanded elements limit reached in RecordOp\n");
+ demanded_limit_reached_ = true;
}
}
}
-std::optional<DemandedBytes> DemandedByteAnalysis::AddUserAndCheckFoundAll(
- const Operation& op, const DemandedBytes& demanded) {
+std::optional<DemandedByteAnalysis::DemandState>
+DemandedByteAnalysis::AddUserAndCheckFoundAll(const Operation& op,
+ DemandState demand) {
for (MultiUserBits& multi_use : to_revisit_) {
if (multi_use.op() == &op) {
- multi_use.Add(demanded);
+ multi_use.Add(demand);
if (multi_use.FoundAllUsers()) {
// Ensure we don't visit this again from the top-level search.
visited_.insert(&op);
TRACE("Found all users (%d) of Op %d, demanded bytes: %#04x\n",
op.saturated_use_count.GetMaybeSaturated(),
input_graph().Index(op).id(),
- static_cast<uint32_t>(multi_use.demanded().bytes()));
- return multi_use.demanded();
+ static_cast<uint32_t>(multi_use.demand().bytes.bytes()));
+ return multi_use.demand();
}
return {};
}
}
if (to_revisit_.size() < kMaxNumOperations) {
- to_revisit_.emplace_back(&op, demanded, 1);
+ to_revisit_.emplace_back(&op, demand, 1);
} else if (!revisit_limit_reached_) {
TRACE("Revisit limit reached\n");
revisit_limit_reached_ = true;
@@ -142,42 +192,123 @@ std::optional<DemandedBytes> DemandedByteAnalysis::AddUserAndCheckFoundAll(
return {};
}
+bool DemandedByteAnalysis::TrySearchThroughPassThru(
+ const Operation& op, DemandState& demand, uint8_t bytes_per_lane) const {
+ if (demand.pass_thru_depth >= kMaxPassThruDepth) {
+ TRACE("Pass-through depth limit reached at Op %d\n",
+ input_graph().Index(op).id());
+ return false;
+ }
+ demand.bytes.WidenToLaneBoundary(bytes_per_lane);
+ ++demand.pass_thru_depth;
+ return true;
+}
+
void DemandedByteAnalysis::RecordPartialOp(const Operation& op,
- DemandedBytes demanded) {
+ DemandState demand) {
+ // Don't record it if we can't reduce it.
+ if (demand.bytes.IsAll()) return;
+
TRACE("Recording partial Op %d, demanded bytes: %#04x\n",
- input_graph().Index(op).id(), static_cast<uint32_t>(demanded.bytes()));
+ input_graph().Index(op).id(),
+ static_cast<uint32_t>(demand.bytes.bytes()));
+
if (auto* unop = op.TryCast<Simd128UnaryOp>()) {
- RecordPartialOp(*unop, demanded);
+ RecordPartialOp(*unop, demand);
} else if (auto* binop = op.TryCast<Simd128BinopOp>()) {
- RecordPartialOp(*binop, demanded);
+ RecordPartialOp(*binop, demand);
+ } else if (auto* shiftop = op.TryCast<Simd128ShiftOp>()) {
+ RecordPartialOp(*shiftop, demand);
+ } else if (auto* ternary = op.TryCast<Simd128TernaryOp>()) {
+ RecordPartialOp(*ternary, demand);
} else if (auto* shuffle = op.TryCast<Simd128ShuffleOp>()) {
- (void)AddUserAndCheckFoundAll(*shuffle, demanded);
+ TRACE("Recording partial ShuffleOp %d, demanded lanes: %#04x\n",
+ input_graph().Index(op).id(),
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ if (AddUserAndCheckFoundAll(*shuffle, demand)) {
+ TRACE("Found all users (%d) of ShuffleOp %d, demanded lanes: %#04x\n",
+ op.saturated_use_count.GetMaybeSaturated(),
+ input_graph().Index(op).id(),
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ }
}
}
void DemandedByteAnalysis::RecordPartialOp(const Simd128UnaryOp& unop,
- DemandedBytes demanded) {
- if (IsUnaryLowHalfOp(unop.kind)) {
+ DemandState demand) {
+ if (IsUnaryLowHalfOp(unop.kind) || IsUnaryPassThruOp(unop.kind)) {
// If we've now visited this unop from all of its users, visit its
// operand.
- if (auto maybe_demanded = AddUserAndCheckFoundAll(unop, demanded)) {
- demanded = maybe_demanded.value();
- demanded.HalveWithLimit(GetInputElementSizeInBytes(unop.kind));
- Add(unop.input(), demanded);
+ if (auto merged = AddUserAndCheckFoundAll(unop, demand)) {
+ demand = *merged;
+ if (IsUnaryLowHalfOp(unop.kind)) {
+ demand.bytes.HalveWithLimit(
+ ElementSizeInBytes(unop.input_element_rep()));
+ } else {
+ if (!TrySearchThroughPassThru(
+ unop, demand, ElementSizeInBytes(unop.input_element_rep()))) {
+ return;
+ }
+ }
+ Add(unop.input(), demand);
}
}
}
void DemandedByteAnalysis::RecordPartialOp(const Simd128BinopOp& binop,
- DemandedBytes demanded) {
- if (IsBinaryLowHalfOp(binop.kind)) {
+ DemandState demand) {
+ if (IsBinaryLowHalfOp(binop.kind) || IsBinaryPassThruOp(binop.kind)) {
// If we've now visited this binop from all of its users, visit its
// operands.
- if (auto maybe_demanded = AddUserAndCheckFoundAll(binop, demanded)) {
- demanded = maybe_demanded.value();
- demanded.HalveWithLimit(GetInputElementSizeInBytes(binop.kind));
- Add(binop.left(), demanded);
- Add(binop.right(), demanded);
+ if (auto merged = AddUserAndCheckFoundAll(binop, demand)) {
+ demand = *merged;
+ if (IsBinaryLowHalfOp(binop.kind)) {
+ demand.bytes.HalveWithLimit(
+ ElementSizeInBytes(binop.input_element_rep()));
+ } else {
+ if (!TrySearchThroughPassThru(
+ binop, demand, ElementSizeInBytes(binop.input_element_rep()))) {
+ return;
+ }
+ }
+ Add(binop.left(), demand);
+ Add(binop.right(), demand);
+ }
+ }
+}
+
+void DemandedByteAnalysis::RecordPartialOp(const Simd128TernaryOp& ternary,
+ DemandState demand) {
+ if (IsTernaryPassThruOp(ternary.kind)) {
+ if (auto merged = AddUserAndCheckFoundAll(ternary, demand)) {
+ demand = *merged;
+ if (!TrySearchThroughPassThru(
+ ternary, demand,
+ ElementSizeInBytes(ternary.input_element_rep()))) {
+ return;
+ }
+ Add(ternary.first(), demand);
+ Add(ternary.second(), demand);
+ Add(ternary.third(), demand);
+ }
+ }
+}
+
+void DemandedByteAnalysis::RecordPartialOp(const Simd128ShiftOp& shiftop,
+ DemandState demand) {
+ if (IsShiftPassThruOp(shiftop.kind)) {
+ if (auto merged = AddUserAndCheckFoundAll(shiftop, demand)) {
+ demand = *merged;
+ if (!TrySearchThroughPassThru(
+ shiftop, demand,
+ ElementSizeInBytes(shiftop.input_element_rep()))) {
+ return;
+ }
+ TRACE("Found all users (%d) of ShiftOp %d, demanded lanes: %#04x\n",
+ shiftop.saturated_use_count.GetMaybeSaturated(),
+ input_graph().Index(shiftop).id(),
+ static_cast<uint32_t>(demand.bytes.bytes()));
+ Add(shiftop.input(), demand);
}
}
}
@@ -207,7 +338,7 @@ void DemandedByteAnalysis::Revisit() {
if (multi_user.FoundAllUsers()) {
const Operation* op = multi_user.op();
if (auto* shuffle = op->TryCast<Simd128ShuffleOp>()) {
- RevisitShuffle(*shuffle, multi_user.demanded());
+ RevisitShuffle(*shuffle, multi_user.demand().bytes);
}
}
}
@@ -229,7 +360,8 @@ namespace {
bool IsTopBottomInterleave(const Simd128ShuffleOp* shuffle_op) {
if (shuffle_op && shuffle_op->left() == shuffle_op->right()) {
std::array<uint8_t, kSimd128Size> shuffle_bytes;
- std::copy_n(shuffle_op->shuffle, kSimd128Size, shuffle_bytes.begin());
+ std::copy_n(shuffle_op->shuffle.begin(), kSimd128Size,
+ shuffle_bytes.begin());
return SimdShuffle::TryMatchCanonical(shuffle_bytes) ==
SimdShuffle::CanonicalShuffle::kS16x8TopBottomInterleave;
}
@@ -575,7 +707,7 @@ bool WasmShuffleAnalyzer::ProcessShuffleOfShuffle(
if (IsShuffleToShift(shuffle_out)) return false;
DemandedBytes shuffle_out_demanded = GetDemandedBytes(&shuffle_out);
- std::span<const uint8_t> shuffle_out_bytes(shuffle_out.shuffle,
+ std::span<const uint8_t> shuffle_out_bytes(shuffle_out.shuffle.data(),
shuffle_out_demanded.bytes());
for (uint8_t bytes : {8, 4, 2, 1}) {
auto shuffle_in_demanded = DemandedBytes::Low(bytes);
@@ -722,7 +854,7 @@ void WasmShuffleAnalyzer::ProcessShuffleOfLoads(const Simd128ShuffleOp& shuffle,
if (GetDemandedBytes(&shuffle).IsAll()) {
// Full width shuffles.
SimdShuffle::ShuffleArray shuffle_bytes;
- std::copy_n(shuffle.shuffle, kSimd128Size, shuffle_bytes.begin());
+ std::copy_n(shuffle.shuffle.begin(), kSimd128Size, shuffle_bytes.begin());
auto canonical = SimdShuffle::TryMatchCanonical(shuffle_bytes);
switch (canonical) {
default:
@@ -796,8 +928,6 @@ void WasmShuffleAnalyzer::ProcessShuffle(const Simd128ShuffleOp& shuffle) {
const Operation& left = input_graph().Get(shuffle.left());
const Operation& right = input_graph().Get(shuffle.right());
-#if V8_TARGET_ARCH_ARM64
-
if (shuffle.kind != Simd128ShuffleOp::Kind::kI8x16) {
return;
}
@@ -833,8 +963,6 @@ void WasmShuffleAnalyzer::ProcessShuffle(const Simd128ShuffleOp& shuffle) {
}
}
-#endif // V8_TARGET_ARCH_ARM64
-
uint8_t max_uses = shuffle.left() == shuffle.right() ? 2 : 1;
if (!reduced_left && left.saturated_use_count.Is(max_uses)) {
TryReduceFromMSB(shuffle.left(), shuffle, ShuffleSide::kLeft);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
index 49be8879c1b..a885df3530b 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
@@ -9,6 +9,7 @@
#ifndef V8_COMPILER_TURBOSHAFT_WASM_SHUFFLE_REDUCER_H_
#define V8_COMPILER_TURBOSHAFT_WASM_SHUFFLE_REDUCER_H_
+#include <algorithm>
#include <optional>
#include "src/base/template-utils.h"
@@ -121,6 +122,14 @@ class DemandedBytes {
}
}
+ void WidenToLaneBoundary(uint8_t bytes_per_lane) {
+ DCHECK(base::bits::IsPowerOfTwo(bytes_per_lane));
+ DCHECK_GE(bytes_per_lane, 1);
+ DCHECK_LE(bytes_per_lane, kSimd128Size);
+ DCHECK(base::bits::IsPowerOfTwo(bytes()));
+ bytes_ = std::max(bytes_, bytes_per_lane);
+ }
+
bool IsLessThanOrEqual(const DemandedBytes& demanded) const {
return bytes() <= demanded.bytes();
}
@@ -147,11 +156,14 @@ class DemandedBytes {
class DemandedByteAnalysis {
public:
- static constexpr int kMaxNumOperations = 150;
+ static constexpr int kMaxNumOperations = 300;
+ static constexpr uint8_t kMaxPassThruDepth = 8;
+
+ struct DemandState {
+ DemandedBytes bytes;
+ uint8_t pass_thru_depth = 0;
+ };
- // TODO(sparker): Add floating-point conversions:
- // - PromoteLow
- // - ConvertLow
static constexpr std::array unary_low_half_ops = {
Simd128UnaryOp::Kind::kI16x8SConvertI8x16Low,
Simd128UnaryOp::Kind::kI16x8UConvertI8x16Low,
@@ -159,6 +171,10 @@ class DemandedByteAnalysis {
Simd128UnaryOp::Kind::kI32x4UConvertI16x8Low,
Simd128UnaryOp::Kind::kI64x2SConvertI32x4Low,
Simd128UnaryOp::Kind::kI64x2UConvertI32x4Low,
+ Simd128UnaryOp::Kind::kF32x4PromoteLowF16x8,
+ Simd128UnaryOp::Kind::kF64x2PromoteLowF32x4,
+ Simd128UnaryOp::Kind::kF64x2ConvertLowI32x4S,
+ Simd128UnaryOp::Kind::kF64x2ConvertLowI32x4U,
};
static constexpr std::array binary_low_half_ops = {
Simd128BinopOp::Kind::kI16x8ExtMulLowI8x16S,
@@ -177,36 +193,17 @@ class DemandedByteAnalysis {
return std::find(binary_low_half_ops.begin(), binary_low_half_ops.end(),
kind) != binary_low_half_ops.end();
}
-
- static uint8_t GetInputElementSizeInBytes(Simd128UnaryOp::Kind kind) {
- switch (kind) {
- default:
- UNREACHABLE();
- case Simd128UnaryOp::Kind::kI16x8SConvertI8x16Low:
- case Simd128UnaryOp::Kind::kI16x8UConvertI8x16Low:
- return 1;
- case Simd128UnaryOp::Kind::kI32x4SConvertI16x8Low:
- case Simd128UnaryOp::Kind::kI32x4UConvertI16x8Low:
- return 2;
- case Simd128UnaryOp::Kind::kI64x2SConvertI32x4Low:
- case Simd128UnaryOp::Kind::kI64x2UConvertI32x4Low:
- return 4;
- }
- }
- static uint8_t GetInputElementSizeInBytes(Simd128BinopOp::Kind kind) {
- switch (kind) {
- default:
- UNREACHABLE();
- case Simd128BinopOp::Kind::kI16x8ExtMulLowI8x16S:
- case Simd128BinopOp::Kind::kI16x8ExtMulLowI8x16U:
- return 1;
- case Simd128BinopOp::Kind::kI32x4ExtMulLowI16x8S:
- case Simd128BinopOp::Kind::kI32x4ExtMulLowI16x8U:
- return 2;
- case Simd128BinopOp::Kind::kI64x2ExtMulLowI32x4S:
- case Simd128BinopOp::Kind::kI64x2ExtMulLowI32x4U:
- return 4;
- }
+ static bool IsUnaryPassThruOp(Simd128UnaryOp::Kind kind) {
+ return v8_flags.future_wasm_simd_opt && Simd128UnaryOp::IsLaneWise(kind);
+ }
+ static bool IsBinaryPassThruOp(Simd128BinopOp::Kind kind) {
+ return v8_flags.future_wasm_simd_opt && Simd128BinopOp::IsLaneWise(kind);
+ }
+ static bool IsShiftPassThruOp(Simd128ShiftOp::Kind kind) {
+ return v8_flags.future_wasm_simd_opt && Simd128ShiftOp::IsLaneWise(kind);
+ }
+ static bool IsTernaryPassThruOp(Simd128TernaryOp::Kind kind) {
+ return v8_flags.future_wasm_simd_opt && Simd128TernaryOp::IsLaneWise(kind);
}
using DemandedByteMap =
@@ -215,12 +212,25 @@ class DemandedByteAnalysis {
DemandedByteAnalysis(Zone* phase_zone, const Graph& input_graph)
: phase_zone_(phase_zone), input_graph_(input_graph) {}
- void Add(OpIndex node, DemandedBytes demanded);
- void AddOp(const Simd128UnaryOp& unop, DemandedBytes demanded);
- void AddOp(const Simd128BinopOp& binop, DemandedBytes demanded);
- void AddOp(const Simd128ExtractLaneOp& extract_op, DemandedBytes demanded);
- void AddOp(const Simd128LaneMemoryOp& lane_op, DemandedBytes demanded);
- void RecordOp(const Operation& op, DemandedBytes demanded);
+ void Add(OpIndex node, DemandedBytes demanded) {
+ Add(node, DemandState{demanded});
+ }
+ void Add(OpIndex node) { Add(node, DemandedBytes::Low(kSimd128Size)); }
+ void RecordOp(const Operation& op, DemandedBytes demanded) {
+ RecordOp(op, DemandState{demanded});
+ }
+ void AddOp(const Simd128UnaryOp& op, DemandedBytes demanded) {
+ AddOp(op, DemandState{demanded});
+ }
+ void AddOp(const Simd128BinopOp& op, DemandedBytes demanded) {
+ AddOp(op, DemandState{demanded});
+ }
+ void AddOp(const Simd128ExtractLaneOp& op, DemandedBytes demanded) {
+ AddOp(op, DemandState{demanded});
+ }
+ void AddOp(const Simd128LaneMemoryOp& op, DemandedBytes demanded) {
+ AddOp(op, DemandState{demanded});
+ }
void Revisit();
const DemandedByteMap& demanded_bytes() const { return demanded_bytes_; }
@@ -232,16 +242,17 @@ class DemandedByteAnalysis {
private:
class MultiUserBits {
public:
- MultiUserBits(const Operation* op, DemandedBytes demanded,
- uint32_t num_users)
- : op_(op), demanded_(demanded), num_users_(num_users) {}
+ MultiUserBits(const Operation* op, DemandState demand, uint32_t num_users)
+ : op_(op), demand_(demand), num_users_(num_users) {}
const Operation* op() const { return op_; }
- DemandedBytes demanded() const { return demanded_; }
+ DemandState demand() const { return demand_; }
uint32_t num_users() const { return num_users_; }
- void Add(const DemandedBytes& bytes) {
- demanded_.Max(bytes);
+ void Add(DemandState demand) {
+ demand_.bytes.Max(demand.bytes);
+ demand_.pass_thru_depth =
+ std::max(demand_.pass_thru_depth, demand.pass_thru_depth);
++num_users_;
}
@@ -252,17 +263,29 @@ class DemandedByteAnalysis {
private:
const Operation* op_;
- DemandedBytes demanded_;
+ DemandState demand_;
uint32_t num_users_;
};
// For the given op, return whether we have now visited it from all of its
// users and so we know all of the used bytes.
- std::optional<DemandedBytes> AddUserAndCheckFoundAll(
- const Operation& op, const DemandedBytes& demanded);
- void RecordPartialOp(const Operation& op, DemandedBytes demanded);
- void RecordPartialOp(const Simd128UnaryOp& unop, DemandedBytes demanded);
- void RecordPartialOp(const Simd128BinopOp& binop, DemandedBytes demanded);
+ std::optional<DemandState> AddUserAndCheckFoundAll(const Operation& op,
+ DemandState demand);
+ bool TrySearchThroughPassThru(const Operation& op, DemandState& demand,
+ uint8_t bytes_per_lane) const;
+ void Add(OpIndex node, DemandState demand);
+ void AddOp(const Simd128UnaryOp& unop, DemandState demand);
+ void AddOp(const Simd128BinopOp& binop, DemandState demand);
+ void AddOp(const Simd128ShiftOp& shiftop, DemandState demand);
+ void AddOp(const Simd128TernaryOp& ternary, DemandState demand);
+ void AddOp(const Simd128ExtractLaneOp& extract_op, DemandState demand);
+ void AddOp(const Simd128LaneMemoryOp& lane_op, DemandState demand);
+ void RecordOp(const Operation& op, DemandState demand);
+ void RecordPartialOp(const Operation& op, DemandState demand);
+ void RecordPartialOp(const Simd128UnaryOp& unop, DemandState demand);
+ void RecordPartialOp(const Simd128BinopOp& binop, DemandState demand);
+ void RecordPartialOp(const Simd128ShiftOp& shiftop, DemandState demand);
+ void RecordPartialOp(const Simd128TernaryOp& ternary, DemandState demand);
void RevisitShuffle(const Simd128ShuffleOp& shuffle, DemandedBytes demanded);
Zone* phase_zone_;
@@ -340,12 +363,14 @@ class WasmShuffleAnalyzer {
}
// Pointer to the beginning of the window.
- const uint8_t* begin() const { return shuffle_->shuffle + begin_index(); }
+ const uint8_t* begin() const {
+ return shuffle_->shuffle.data() + begin_index();
+ }
// Pointer to the past-the-end element of the window.
const uint8_t* end() const {
if (begin_index() + OutputDemanded().bytes() >= kSimd128Size) {
- return shuffle()->shuffle + kSimd128Size;
+ return shuffle()->shuffle.data() + kSimd128Size;
}
return begin() + OutputDemanded().bytes();
}
@@ -760,7 +785,7 @@ class WasmShuffleReducer : public Next {
#endif // V8_TARGET_ARCH_ARM64
std::array<uint8_t, kSimd128Size> shuffle_bytes = {0};
- std::copy(shuffle.shuffle, shuffle.shuffle + kSimd128Size,
+ std::copy(shuffle.shuffle.begin(), shuffle.shuffle.end(),
shuffle_bytes.begin());
DemandedBytes demanded_bytes = analyzer_->GetDemandedBytes(&shuffle);
bool emit_new_shuffle = !demanded_bytes.IsLow(kSimd128Size);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h b/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
index d15cb3b948c..1e95485f25d 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
@@ -266,8 +266,8 @@ auto WasmWrapperTSGraphBuilder<Assembler>::BuildJSToWasmWrapper(
// We only need a `caller_frame_state` if there actually are arguments to
// convert.
const int wasm_param_count = static_cast<int>(sig_->parameter_count());
- DCHECK_EQ(is_inlining_into_js_ && wasm_param_count > 0,
- caller_frame_state.valid());
+ CHECK_EQ(is_inlining_into_js_ && wasm_param_count > 0,
+ caller_frame_state.valid());
__ Bind(__ NewBlock());
@@ -311,29 +311,10 @@ auto WasmWrapperTSGraphBuilder<Assembler>::BuildJSToWasmWrapper(
return OpIndex::Invalid();
}
- V<SharedFunctionInfo> sfi =
- __ Load(js_closure, LoadOp::Kind::TaggedBase().Immutable(),
- MemoryRepresentation::TaggedPointer(),
- offsetof(JSFunction, shared_function_info_));
- V<WasmFunctionData> function_data =
- V<WasmFunctionData>::Cast(__ LoadTrustedPointer(
- sfi, LoadOp::Kind::TaggedBase().Immutable(),
- kWasmExportedFunctionDataIndirectPointerTag,
- offsetof(SharedFunctionInfo, trusted_function_data_)));
-
- // If we are not inlining the Wasm body, we don't need the Wasm instance.
- V<WasmTrustedInstanceData> instance_data =
- inlined_function_data_.has_value()
- ? V<WasmTrustedInstanceData>::Cast(__ LoadProtectedPointerField(
- function_data, LoadOp::Kind::TaggedBase().Immutable(),
- offsetof(WasmExportedFunctionData, protected_instance_data_)))
- : OpIndex::Invalid();
-
// Convert JS parameters to wasm numbers using the default transformation
// and build the call.
const int args_count = wasm_param_count + /* instance_data */ 1;
base::SmallVector<OpIndex, 16> args(args_count);
- args[0] = instance_data;
for (int i = 0; i < wasm_param_count; ++i) {
OptionalOpIndex arg =
FromJS(params[i], js_context, sig_->GetParam(i), caller_frame_state);
@@ -350,6 +331,7 @@ auto WasmWrapperTSGraphBuilder<Assembler>::BuildJSToWasmWrapper(
if constexpr (requires { &Assembler::TryInlineWasmBody; }) {
if (inlined_function_data_.has_value()) {
CHECK(v8_flags.wasm_in_js_inlining_body);
+ args[0] = __ WasmInstanceData();
inlining_result = __ TryInlineWasmBody(
inlined_function_data_.value(), VectorOf(args), lazy_deopt_on_throw);
// If the body inlining traps unconditionally (e.g., due to an
@@ -367,6 +349,12 @@ auto WasmWrapperTSGraphBuilder<Assembler>::BuildJSToWasmWrapper(
// If the wasm function was not inlined, we need to call it.
if (!inlining_result.success) {
+ V<SharedFunctionInfo> sfi = LoadSharedFunctionInfo(js_closure);
+ V<WasmFunctionData> function_data =
+ V<WasmFunctionData>::Cast(__ LoadTrustedPointer(
+ sfi, LoadOp::Kind::TaggedBase().Immutable(),
+ kWasmExportedFunctionDataIndirectPointerTag,
+ offsetof(SharedFunctionInfo, trusted_function_data_)));
V<WasmInternalFunction> internal =
V<WasmInternalFunction>::Cast(__ LoadProtectedPointerField(
function_data, LoadOp::Kind::TaggedBase().Immutable(),
@@ -506,9 +494,10 @@ void WasmWrapperTSGraphBuilder<Assembler>::BuildWasmToJSWrapper(
call_descriptor, compiler::CanThrow{true},
compiler::LazyDeoptOnThrow{false}, __ graph_zone());
+ V<Context> callee_context = LoadContextFromJSFunction(callable_node);
// Determine receiver at runtime.
args[0] =
- BuildReceiverNode(callable_node, native_context, undefined_node);
+ BuildReceiverNode(callable_node, callee_context, undefined_node);
DCHECK_EQ(pos, pushed_count + 1);
args[pos++] = undefined_node; // new target
args[pos++] =
@@ -516,7 +505,7 @@ void WasmWrapperTSGraphBuilder<Assembler>::BuildWasmToJSWrapper(
#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
args[pos++] = __ Word32Constant(kPlaceholderDispatchHandle.value());
#endif
- args[pos++] = LoadContextFromJSFunction(callable_node);
+ args[pos++] = callee_context;
call = __ Call(callable_node, OpIndex::Invalid(), base::VectorOf(args),
ts_call_descriptor);
break;
diff --git a/deps/v8/src/compiler/turboshaft/wasm-wrappers.h b/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
index 3bccdab1a64..e4376ecfbc9 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
@@ -600,7 +600,7 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
V<Float32> BuildChangeTaggedToFloat32(
V<Object> value, V<Context> context,
OptionalV<EagerFrameState> caller_frame_state) {
- DCHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
+ CHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
ScopedVar<Float32> result(this, V<Float32>::Invalid());
IF (__ IsSmi(value)) {
// TODO(dlehmann,wasm-runtime): If `ChangeInt32ToFloat32(x)` is exactly
@@ -640,7 +640,7 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
V<Float64> BuildChangeTaggedToFloat64(
V<Object> value, V<Context> context,
OptionalV<EagerFrameState> caller_frame_state) {
- DCHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
+ CHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
ScopedVar<Float64> result(this, V<Float64>::Invalid());
IF (__ IsSmi(value)) {
result = __ ChangeInt32ToFloat64(__ UntagSmi(V<Smi>::Cast(value)));
@@ -672,7 +672,7 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
V<Word32> BuildChangeTaggedToInt32(
V<Object> value, V<Context> context,
OptionalV<EagerFrameState> caller_frame_state) {
- DCHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
+ CHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
if (is_inlining_into_js_) {
// When inlining into JS, emit a "high-level" JS conversion to allow
// further optimizations. These are lowered in the MachineLoweringPhase
@@ -708,7 +708,7 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
OpIndex BuildChangeBigIntToInt64(
V<Object> input, V<Context> context,
OptionalV<EagerFrameState> caller_frame_state) {
- DCHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
+ CHECK_EQ(is_inlining_into_js_, caller_frame_state.valid());
// When inlining JS-to-Wasm wrappers, eagerly deopt for values that are
// not BigInt to avoid calling ToBigInt, which could trigger user JS via
// valueOf/Symbol.toPrimitive (same rationale as for i32/f32/f64).
@@ -901,8 +901,9 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
compiler::AccessBuilder::ForJSFunctionSharedFunctionInfo());
}
- OpIndex BuildReceiverNode(OpIndex callable_node, OpIndex native_context,
- V<Undefined> undefined_node) {
+ V<Object> BuildReceiverNode(V<JSFunction> callable_node,
+ V<Context> callee_context,
+ V<Undefined> undefined_node) {
// Check function strict bit.
V<SharedFunctionInfo> shared_function_info =
LoadSharedFunctionInfo(callable_node);
@@ -918,8 +919,14 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
IF (strict_check) {
strict_d = undefined_node;
} ELSE {
- strict_d =
- __ LoadFixedArrayElement(native_context, Context::GLOBAL_PROXY_INDEX);
+ V<Map> context_map = LoadMap(callee_context);
+ V<NativeContext> callee_native_context =
+ __ template LoadField<NativeContext>(
+ context_map, compiler::AccessBuilder::ForMapNativeContext());
+ strict_d = __ template LoadField<Object>(
+ callee_native_context,
+ compiler::AccessBuilder::ForContextSlotKnownPointer(
+ Context::GLOBAL_PROXY_INDEX));
}
return strict_d;
}
diff --git a/deps/v8/src/compiler/wasm-compiler-definitions.h b/deps/v8/src/compiler/wasm-compiler-definitions.h
index 7c04a8138a1..c9a380ecd18 100644
--- a/deps/v8/src/compiler/wasm-compiler-definitions.h
+++ b/deps/v8/src/compiler/wasm-compiler-definitions.h
@@ -70,6 +70,9 @@ struct WasmTypeCheckConfig {
from.is_ref() && to.is_ref() &&
wasm::IsSameTypeHierarchy(from.heap_type(), to.heap_type());
}
+
+ friend bool operator==(const WasmTypeCheckConfig&,
+ const WasmTypeCheckConfig&) = default;
};
V8_INLINE std::ostream& operator<<(std::ostream& os,
@@ -78,12 +81,8 @@ V8_INLINE std::ostream& operator<<(std::ostream& os,
}
V8_INLINE size_t hash_value(WasmTypeCheckConfig const& p) {
- return base::hash_combine(p.from.raw_bit_field(), p.to.raw_bit_field());
-}
-
-V8_INLINE bool operator==(const WasmTypeCheckConfig& p1,
- const WasmTypeCheckConfig& p2) {
- return p1.from == p2.from && p1.to == p2.to;
+ return base::hash_combine(p.from.raw_bit_field(), p.to.raw_bit_field(),
+ p.exactness);
}
static constexpr int kCharWidthBailoutSentinel = 3;
diff --git a/deps/v8/src/d8/d8-test.cc b/deps/v8/src/d8/d8-test.cc
index a6dd1f5785e..425f48a1166 100644
--- a/deps/v8/src/d8/d8-test.cc
+++ b/deps/v8/src/d8/d8-test.cc
@@ -2147,7 +2147,7 @@ namespace {
v8::Intercepted D8InterceptCallback(Local<Name> property,
const PropertyCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
- Local<Value> data = info.Data();
+ Local<Value> data = info.DataV2().As<Value>();
if (!data->IsFunction()) {
isolate->ThrowError("Interceptor callback must be a function");
return v8::Intercepted::kYes;
@@ -2235,8 +2235,7 @@ bool D8AccessCheck(Local<Context> accessing_context,
void Shell::CreateInterceptorObject(const FunctionCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
if (info.Length() == 0 || !info[0]->IsFunction()) {
- isolate->ThrowError(
- "d8.test.createInterceptorObject requires a getter function");
+ isolate->ThrowError("Usage: d8.test.createInterceptorObject(function)");
return;
}
Local<Context> context = isolate->GetCurrentContext();
@@ -2255,8 +2254,7 @@ void Shell::CreateInterceptorObject(const FunctionCallbackInfo<Value>& info) {
void Shell::CreateAccessCheckedObject(const FunctionCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
if (info.Length() == 0) {
- isolate->ThrowError(
- "d8.test.createAccessCheckedObject requires a policy argument");
+ isolate->ThrowError("Usage: d8.test.createAccessCheckedObject(policy)");
return;
}
AccessPolicy policy;
@@ -2278,6 +2276,39 @@ void Shell::CreateAccessCheckedObject(const FunctionCallbackInfo<Value>& info) {
info.GetReturnValue().Set(instance);
}
+void Shell::CreateAccessCheckedInterceptorObject(
+ const FunctionCallbackInfo<Value>& info) {
+ Isolate* isolate = info.GetIsolate();
+ if (info.Length() < 2 || !info[1]->IsFunction()) {
+ isolate->ThrowError(
+ "Usage: d8.test.createAccessCheckedInterceptorObject(policy, "
+ "function)");
+ return;
+ }
+ AccessPolicy policy;
+ if (!ParseAccessPolicy(isolate, info[0], &policy)) return;
+
+ Local<Context> context = isolate->GetCurrentContext();
+ Local<FunctionTemplate> ctor = FunctionTemplate::New(isolate);
+ Local<ObjectTemplate> templ = ctor->InstanceTemplate();
+
+ templ->SetInternalFieldCount(1);
+ templ->SetAccessCheckCallbackAndHandler(
+ D8AccessCheck,
+ NamedPropertyHandlerConfiguration(D8InterceptCallback, nullptr, nullptr,
+ nullptr, nullptr, info[1]),
+ IndexedPropertyHandlerConfiguration());
+
+ Local<Function> fn;
+ if (!ctor->GetFunction(context).ToLocal(&fn)) return;
+ Local<Object> instance;
+ if (!fn->NewInstance(context).ToLocal(&instance)) return;
+ instance->SetAlignedPointerInInternalField(
+ 0, reinterpret_cast<void*>(static_cast<uintptr_t>(policy)),
+ kEmbedderDataTypeTagDefault);
+ info.GetReturnValue().Set(instance);
+}
+
void Shell::SetAccessPolicy(const FunctionCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
if (info.Length() < 2 || !info[0]->IsObject()) {
@@ -2297,72 +2328,4 @@ void Shell::SetAccessPolicy(const FunctionCallbackInfo<Value>& info) {
kEmbedderDataTypeTagDefault);
}
-void Shell::CreateSpecialObject(const FunctionCallbackInfo<Value>& info) {
- Isolate* isolate = info.GetIsolate();
- if (info.Length() == 0 || !info[0]->IsObject()) {
- isolate->ThrowError(
- "d8.test.createSpecialObject requires an options object");
- return;
- }
- Local<Context> context = isolate->GetCurrentContext();
- Local<Object> opts = info[0].As<Object>();
-
- bool has_interceptor = false;
- bool has_access_check = false;
- Local<Value> interceptor_data = Undefined(isolate);
- AccessPolicy access_policy = AccessPolicy::kAllow;
-
- Local<Value> inc;
- if (opts->Get(context, String::NewFromUtf8Literal(isolate, "interceptor"))
- .ToLocal(&inc) &&
- !inc->IsUndefined()) {
- if (!inc->IsFunction()) {
- isolate->ThrowError("interceptor option must be a function");
- return;
- }
- has_interceptor = true;
- interceptor_data = inc;
- }
-
- Local<Value> ac;
- if (opts->Get(context, String::NewFromUtf8Literal(isolate, "accessCheck"))
- .ToLocal(&ac) &&
- !ac->IsUndefined()) {
- if (!ParseAccessPolicy(isolate, ac, &access_policy)) {
- return;
- }
- has_access_check = true;
- }
-
- Local<FunctionTemplate> ctor = FunctionTemplate::New(isolate);
- Local<ObjectTemplate> templ = ctor->InstanceTemplate();
- if (has_access_check) {
- templ->SetInternalFieldCount(1);
- }
- if (has_interceptor && has_access_check) {
- templ->SetAccessCheckCallbackAndHandler(
- D8AccessCheck,
- NamedPropertyHandlerConfiguration(D8InterceptCallback, nullptr, nullptr,
- nullptr, nullptr, interceptor_data),
- IndexedPropertyHandlerConfiguration());
- } else if (has_interceptor) {
- templ->SetHandler(
- NamedPropertyHandlerConfiguration(D8InterceptCallback, nullptr, nullptr,
- nullptr, nullptr, interceptor_data));
- } else if (has_access_check) {
- templ->SetAccessCheckCallback(D8AccessCheck);
- }
-
- Local<Function> fn;
- if (!ctor->GetFunction(context).ToLocal(&fn)) return;
- Local<Object> instance;
- if (!fn->NewInstance(context).ToLocal(&instance)) return;
- if (has_access_check) {
- instance->SetAlignedPointerInInternalField(
- 0, reinterpret_cast<void*>(static_cast<uintptr_t>(access_policy)),
- kEmbedderDataTypeTagDefault);
- }
- info.GetReturnValue().Set(instance);
-}
-
} // namespace v8
diff --git a/deps/v8/src/d8/d8.cc b/deps/v8/src/d8/d8.cc
index 12799d598dd..8d325f418e3 100644
--- a/deps/v8/src/d8/d8.cc
+++ b/deps/v8/src/d8/d8.cc
@@ -55,6 +55,7 @@
#include "src/base/strong-alias.h"
#include "src/base/sys-info.h"
#include "src/base/utils/random-number-generator.h"
+#include "src/codegen/compilation-cache.h"
#include "src/codegen/compiler.h"
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/d8/d8-console.h"
@@ -173,100 +174,47 @@ Isolate::CreateParams GetDefaultIsolateCreateParams() {
return create_params;
}
-// Base class for shell ArrayBuffer allocators. It forwards all operations to
-// the default v8 allocator.
-class ArrayBufferAllocatorBase : public v8::ArrayBuffer::Allocator {
+// ArrayBuffer allocator that never allocates over 10MB.
+class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
+ explicit MockArrayBufferAllocator(v8::ArrayBuffer::Allocator* allocator)
+ : allocator_(allocator) {}
+
+ protected:
void* Allocate(size_t length) override {
- return allocator_->Allocate(length);
+ return allocator_->Allocate(Adjust(length));
}
void* AllocateUninitialized(size_t length) override {
- return allocator_->AllocateUninitialized(length);
+ return allocator_->AllocateUninitialized(Adjust(length));
}
void Free(void* data, size_t length) override {
- allocator_->Free(data, length);
+ allocator_->Free(data, Adjust(length));
}
PageAllocator* GetPageAllocator() override {
return allocator_->GetPageAllocator();
}
- private:
- std::unique_ptr<Allocator> allocator_ =
- std::unique_ptr<Allocator>(NewDefaultAllocator());
-};
-
-// ArrayBuffer allocator that can use virtual memory to improve performance.
-class ShellArrayBufferAllocator : public ArrayBufferAllocatorBase {
- public:
- void* Allocate(size_t length) override {
- if (length >= kVMThreshold) return AllocateVM(length);
- return ArrayBufferAllocatorBase::Allocate(length);
- }
-
- void* AllocateUninitialized(size_t length) override {
- if (length >= kVMThreshold) return AllocateVM(length);
- return ArrayBufferAllocatorBase::AllocateUninitialized(length);
- }
-
- void Free(void* data, size_t length) override {
- if (length >= kVMThreshold) {
- FreeVM(data, length);
- } else {
- ArrayBufferAllocatorBase::Free(data, length);
- }
- }
-
- private:
- static constexpr size_t kVMThreshold = 65536;
-
- void* AllocateVM(size_t length) {
- DCHECK_LE(kVMThreshold, length);
- v8::PageAllocator* page_allocator = GetPageAllocator();
- size_t page_size = page_allocator->AllocatePageSize();
- size_t allocated = RoundUp(length, page_size);
- return i::AllocatePages(page_allocator, allocated, page_size,
- PageAllocator::kReadWrite);
- }
-
- void FreeVM(void* data, size_t length) {
- v8::PageAllocator* page_allocator = GetPageAllocator();
- size_t page_size = page_allocator->AllocatePageSize();
- size_t allocated = RoundUp(length, page_size);
- i::FreePages(page_allocator, data, allocated);
- }
-};
-
-// ArrayBuffer allocator that never allocates over 10MB.
-class MockArrayBufferAllocator : public ArrayBufferAllocatorBase {
- protected:
- void* Allocate(size_t length) override {
- return ArrayBufferAllocatorBase::Allocate(Adjust(length));
- }
-
- void* AllocateUninitialized(size_t length) override {
- return ArrayBufferAllocatorBase::AllocateUninitialized(Adjust(length));
- }
-
- void Free(void* data, size_t length) override {
- return ArrayBufferAllocatorBase::Free(data, Adjust(length));
- }
-
private:
size_t Adjust(size_t length) {
const size_t kAllocationLimit = 10 * i::MB;
return length > kAllocationLimit ? i::AllocatePageSize() : length;
}
+
+ v8::ArrayBuffer::Allocator* allocator_;
};
// ArrayBuffer allocator that can be equipped with a limit to simulate system
// OOM.
-class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
+class MockArrayBufferAllocatorWithLimit : public MockArrayBufferAllocator {
public:
- explicit MockArrayBufferAllocatiorWithLimit(size_t allocation_limit)
- : limit_(allocation_limit), space_left_(allocation_limit) {}
+ MockArrayBufferAllocatorWithLimit(v8::ArrayBuffer::Allocator* allocator,
+ size_t allocation_limit)
+ : MockArrayBufferAllocator(allocator),
+ limit_(allocation_limit),
+ space_left_(allocation_limit) {}
protected:
void* Allocate(size_t length) override {
@@ -287,7 +235,7 @@ class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
void Free(void* data, size_t length) override {
space_left_ += length;
- return MockArrayBufferAllocator::Free(data, length);
+ MockArrayBufferAllocator::Free(data, length);
}
size_t MaxAllocationSize() const override { return limit_; }
@@ -307,11 +255,15 @@ class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
// The purpose is to allow stability-testing of huge (typed) arrays without
// actually consuming huge amounts of physical memory.
// This is currently only available on Linux because it relies on {mremap}.
-class MultiMappedAllocator : public ArrayBufferAllocatorBase {
+class MultiMappedAllocator : public v8::ArrayBuffer::Allocator {
+ public:
+ explicit MultiMappedAllocator(v8::ArrayBuffer::Allocator* allocator)
+ : allocator_(allocator) {}
+
protected:
void* Allocate(size_t length) override {
if (length < kChunkSize) {
- return ArrayBufferAllocatorBase::Allocate(length);
+ return allocator_->Allocate(length);
}
// We use mmap, which initializes pages to zero anyway.
return AllocateUninitialized(length);
@@ -319,7 +271,7 @@ class MultiMappedAllocator : public ArrayBufferAllocatorBase {
void* AllocateUninitialized(size_t length) override {
if (length < kChunkSize) {
- return ArrayBufferAllocatorBase::AllocateUninitialized(length);
+ return allocator_->AllocateUninitialized(length);
}
size_t rounded_length = RoundUp(length, kChunkSize);
int prot = PROT_READ | PROT_WRITE;
@@ -393,7 +345,8 @@ class MultiMappedAllocator : public ArrayBufferAllocatorBase {
void Free(void* data, size_t length) override {
if (length < kChunkSize) {
- return ArrayBufferAllocatorBase::Free(data, length);
+ allocator_->Free(data, length);
+ return;
}
base::MutexGuard lock_guard(®ions_mutex_);
void* real_alloc = regions_[data];
@@ -408,10 +361,15 @@ class MultiMappedAllocator : public ArrayBufferAllocatorBase {
regions_.erase(data);
}
+ PageAllocator* GetPageAllocator() override {
+ return allocator_->GetPageAllocator();
+ }
+
private:
// Aiming for a "Huge Page" (2M on Linux x64) to go easy on the TLB.
static constexpr size_t kChunkSize = 2 * 1024 * 1024;
+ v8::ArrayBuffer::Allocator* allocator_;
std::unordered_map<void*, void*> regions_;
base::Mutex regions_mutex_;
};
@@ -1874,7 +1832,7 @@ void Shell::ModuleResolutionSuccessCallback(
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate(info.GetIsolate());
HandleScope handle_scope(isolate);
- Local<Array> module_resolution_data(info.Data().As<Array>());
+ Local<Array> module_resolution_data(info.DataV2().As<Value>().As<Array>());
Local<Context> context(isolate->GetCurrentContext());
Local<Promise::Resolver> resolver(
@@ -1899,7 +1857,7 @@ void Shell::ModuleResolutionFailureCallback(
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate(info.GetIsolate());
HandleScope handle_scope(isolate);
- Local<Array> module_resolution_data(info.Data().As<Array>());
+ Local<Array> module_resolution_data(info.DataV2().As<Value>().As<Array>());
Local<Context> context(isolate->GetCurrentContext());
Local<Promise::Resolver> resolver(
@@ -3959,7 +3917,7 @@ void Shell::SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& info) {
void Shell::GetContinuationPreservedEmbedderData(
const v8::FunctionCallbackInfo<v8::Value>& info) {
Isolate* isolate = info.GetIsolate();
- Local<Data> data = isolate->GetContinuationPreservedEmbedderDataV2();
+ Local<Data> data = isolate->GetContinuationPreservedEmbedderData();
DCHECK(!data.IsEmpty());
if (!data->IsValue()) {
data = Undefined(isolate);
@@ -5064,8 +5022,9 @@ Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
isolate, "createAccessCheckedObject",
FunctionTemplate::New(isolate, Shell::CreateAccessCheckedObject));
test_template->Set(
- isolate, "createSpecialObject",
- FunctionTemplate::New(isolate, Shell::CreateSpecialObject));
+ isolate, "createAccessCheckedInterceptorObject",
+ FunctionTemplate::New(isolate,
+ Shell::CreateAccessCheckedInterceptorObject));
test_template->Set(isolate, "setAccessPolicy",
FunctionTemplate::New(isolate, Shell::SetAccessPolicy));
@@ -6915,8 +6874,8 @@ void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& info) {
std::unique_ptr<SerializationData> data =
Shell::SerializeValue(isolate, message, transfer);
if (data) {
- DCHECK(info.Data()->IsExternal());
- Local<External> this_value = info.Data().As<External>();
+ DCHECK(info.DataV2().As<Value>()->IsExternal());
+ Local<External> this_value = info.DataV2().As<External>();
Worker* worker = static_cast<Worker*>(this_value->Value(kWorkerTag));
worker->out_queue_.Enqueue(std::move(data));
@@ -6935,8 +6894,8 @@ void Worker::Close(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
- DCHECK(info.Data()->IsExternal());
- Local<External> this_value = info.Data().As<External>();
+ DCHECK(info.DataV2().As<Value>()->IsExternal());
+ Local<External> this_value = info.DataV2().As<External>();
Worker* worker = static_cast<Worker*>(this_value->Value(kWorkerTag));
worker->Terminate();
}
@@ -7557,9 +7516,40 @@ void Shell::CollectGarbage(Isolate* isolate) {
}
namespace {
+
+// Concurrent compilation doesn't post a task when a job finishes; instead it
+// requests an interrupt which finalizes the job the next time JavaScript runs.
+// Since we might not run any JavaScript any more, wait for the jobs and install
+// their code explicitly. Returns true if any job was finalized.
+bool FinalizeBackgroundCompilationJobs(i::Isolate* i_isolate) {
+ i_isolate->WaitForConcurrentOptimizationJobs();
+ // Note that we must not handle the interrupts instead: we're not running
+ // JavaScript and there's no current context, which the handlers of the other
+ // interrupts (e.g. the API interrupt the inspector uses for pausing) rely on.
+ i::StackGuard* stack_guard = i_isolate->stack_guard();
+ bool has_finished_jobs = false;
+ if (stack_guard->CheckInstallCode()) {
+ stack_guard->ClearInstallCode();
+ i_isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
+ has_finished_jobs = true;
+ }
+#ifdef V8_ENABLE_MAGLEV
+ if (stack_guard->CheckInstallMaglevCode()) {
+ stack_guard->ClearInstallMaglevCode();
+ i_isolate->maglev_concurrent_dispatcher()->FinalizeFinishedJobs();
+ has_finished_jobs = true;
+ }
+#endif // V8_ENABLE_MAGLEV
+ return has_finished_jobs;
+}
+
bool ProcessMessages(
Isolate* isolate,
- const std::function<platform::MessageLoopBehavior()>& behavior) {
+ const std::function<platform::MessageLoopBehavior()>& behavior,
+ bool wait_for_background_tasks = false) {
+ // TODO(marja): now we need to pass the MessageLoopBehavior and
+ // wait_for_background_tasks separately - can they be merged?
+
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::SaveAndSwitchContext saved_context(i_isolate, {});
SealHandleScope shs(isolate);
@@ -7596,7 +7586,14 @@ bool ProcessMessages(
}
}
- if (!ran_a_task) break;
+ if (!ran_a_task) {
+ if (!wait_for_background_tasks) break;
+ if (!FinalizeBackgroundCompilationJobs(i_isolate)) break;
+ if (isolate->IsExecutionTerminating()) {
+ return exit_with_success;
+ }
+ DCHECK(!try_catch.HasCaught());
+ }
}
if (g_default_platform->IdleTasksEnabled(isolate)) {
v8::platform::RunIdleTasks(g_default_platform, isolate,
@@ -7630,7 +7627,8 @@ bool Shell::CompleteMessageLoop(Isolate* isolate) {
}
return ran_tasks;
}
- return ProcessMessages(isolate, get_waiting_behaviour);
+ return ProcessMessages(isolate, get_waiting_behaviour,
+ options.wait_for_background_tasks);
}
bool Shell::FinishExecuting(Isolate* isolate, const Global<Context>& context) {
@@ -8031,9 +8029,11 @@ int Shell::Main(int argc, char* argv[]) {
v8::base::EnsureConsoleOutput();
// TODO(40925855): Enable this more broadly outside of d8.
-#if defined(PA_ENABLE_USER_SPACE_ZERO_SEGMENT)
+#if defined(V8_ENABLE_PARTITION_ALLOC)
+#if PA_BUILDFLAG(ENABLE_USER_SPACE_ZERO_SEGMENT)
i::v8_flags.sandbox_prohibit_insecure_mode = true;
-#endif
+#endif // PA_BUILDFLAG(ENABLE_USER_SPACE_ZERO_SEGMENT)
+#endif // defined(V8_ENABLE_PARTITION_ALLOC)
if (!v8::Shell::SetOptions(argc, argv)) return 1;
@@ -8181,16 +8181,18 @@ int Shell::Main(int argc, char* argv[]) {
int result = 0;
Isolate::CreateParams create_params = GetDefaultIsolateCreateParams();
- ShellArrayBufferAllocator shell_array_buffer_allocator;
- MockArrayBufferAllocator mock_arraybuffer_allocator;
+ std::unique_ptr<v8::ArrayBuffer::Allocator> default_allocator(
+ v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ MockArrayBufferAllocator mock_arraybuffer_allocator(default_allocator.get());
const size_t memory_limit =
options.mock_arraybuffer_allocator_limit * options.num_isolates;
- MockArrayBufferAllocatiorWithLimit mock_arraybuffer_allocator_with_limit(
+ MockArrayBufferAllocatorWithLimit mock_arraybuffer_allocator_with_limit(
+ default_allocator.get(),
memory_limit >= options.mock_arraybuffer_allocator_limit
? memory_limit
: std::numeric_limits<size_t>::max());
#ifdef V8_OS_LINUX
- MultiMappedAllocator multi_mapped_mock_allocator;
+ MultiMappedAllocator multi_mapped_mock_allocator(default_allocator.get());
#endif // V8_OS_LINUX
if (options.mock_arraybuffer_allocator) {
if (memory_limit) {
@@ -8203,7 +8205,7 @@ int Shell::Main(int argc, char* argv[]) {
Shell::array_buffer_allocator = &multi_mapped_mock_allocator;
#endif // V8_OS_LINUX
} else {
- Shell::array_buffer_allocator = &shell_array_buffer_allocator;
+ Shell::array_buffer_allocator = default_allocator.get();
}
create_params.array_buffer_allocator = Shell::array_buffer_allocator;
#ifdef ENABLE_VTUNE_JIT_INTERFACE
@@ -8301,6 +8303,10 @@ int Shell::Main(int argc, char* argv[]) {
// Fuzzilli REPRL = read-eval-print-loop
do {
#ifdef V8_FUZZILLI
+ v8::internal::Isolate* internal_isolate =
+ reinterpret_cast<v8::internal::Isolate*>(isolate);
+ internal_isolate->descriptor_lookup_cache()->Clear();
+ internal_isolate->compilation_cache()->Clear();
if (fuzzilli_reprl) {
unsigned action = 0;
ssize_t nread = read(REPRL_CRFD, &action, 4);
diff --git a/deps/v8/src/d8/d8.h b/deps/v8/src/d8/d8.h
index c6a696def8e..eae46fa9d05 100644
--- a/deps/v8/src/d8/d8.h
+++ b/deps/v8/src/d8/d8.h
@@ -1017,7 +1017,7 @@ class Shell : public i::AllStatic {
const v8::FunctionCallbackInfo<v8::Value>& info);
static void CreateAccessCheckedObject(
const v8::FunctionCallbackInfo<v8::Value>& info);
- static void CreateSpecialObject(
+ static void CreateAccessCheckedInterceptorObject(
const v8::FunctionCallbackInfo<v8::Value>& info);
static void SetAccessPolicy(const v8::FunctionCallbackInfo<v8::Value>& info);
diff --git a/deps/v8/src/date/date.h b/deps/v8/src/date/date.h
index 83e1933daf3..88b088ee585 100644
--- a/deps/v8/src/date/date.h
+++ b/deps/v8/src/date/date.h
@@ -100,10 +100,15 @@ class V8_EXPORT_PRIVATE DateCache {
return *name;
}
- // ECMA 262 - 15.9.5.26
+ // The offset of UTC from local time. Not always a whole number of minutes:
+ // local mean time offsets have second precision.
+ int TimezoneOffsetMs(int64_t time_ms) {
+ return static_cast<int>(time_ms - ToLocal(time_ms));
+ }
+
+ // ECMA 262 - https://tc39.es/ecma262/#sec-timezoneestring
int TimezoneOffset(int64_t time_ms) {
- int64_t local_ms = ToLocal(time_ms);
- return static_cast<int>((time_ms - local_ms) / kMsPerMin);
+ return TimezoneOffsetMs(time_ms) / kMsPerMin;
}
// ECMA 262 - https://tc39.es/ecma262/#sec-localtime-t
diff --git a/deps/v8/src/debug/debug-block-list.cc b/deps/v8/src/debug/debug-block-list.cc
new file mode 100644
index 00000000000..7990fbc040d
--- /dev/null
+++ b/deps/v8/src/debug/debug-block-list.cc
@@ -0,0 +1,130 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/debug/debug-block-list.h"
+
+#include <optional>
+
+#include "src/codegen/compiler.h"
+#include "src/debug/debug-scope-info.h"
+#include "src/execution/isolate.h"
+#include "src/objects/scope-info-inl.h"
+#include "src/objects/script-inl.h"
+#include "src/objects/shared-function-info-inl.h"
+#include "src/objects/string-set-inl.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+Handle<StringSet> AddScopeStackLocalsToBlockList(Isolate* isolate,
+ Handle<StringSet> blocklist,
+ DebugScriptScope scope) {
+ if (scope.is_hidden() || scope.is_script_scope()) {
+ return blocklist;
+ }
+ for (int i = 0; i < scope.variable_count(); ++i) {
+ DebugVariableInfo var = scope.variable(i);
+ if (var.location == VariableLocation::PARAMETER ||
+ var.location == VariableLocation::LOCAL) {
+ DirectHandle<String> name(var.name, isolate);
+ blocklist = StringSet::Add(isolate, blocklist, name);
+ }
+ }
+ return blocklist;
+}
+
+} // namespace
+
+Handle<StringSet> EnsureLocalsBlockList(
+ Isolate* isolate, DirectHandle<SharedFunctionInfo> shared_info) {
+ IsCompiledScope is_compiled_scope(shared_info->is_compiled_scope(isolate));
+ if (!is_compiled_scope.is_compiled() &&
+ !Compiler::Compile(isolate, handle(*shared_info, isolate),
+ Compiler::CLEAR_EXCEPTION, &is_compiled_scope)) {
+ return StringSet::New(isolate);
+ }
+
+ DirectHandle<ScopeInfo> closure_scope_info(shared_info->scope_info(),
+ isolate);
+ Tagged<UnionOf<TheHole, StringSet>> existing =
+ isolate->LocalsBlockListCacheGet(closure_scope_info);
+ if (IsStringSet(existing)) {
+ return handle(Cast<StringSet>(existing), isolate);
+ }
+
+ if (!IsScript(shared_info->script())) {
+ return StringSet::New(isolate);
+ }
+ DirectHandle<Script> script(Cast<Script>(shared_info->script()), isolate);
+ Handle<DebugScriptScopeInfo> debug_scope_info =
+ EnsureDebugScriptScopeInfo(isolate, script);
+ if (debug_scope_info.is_null()) {
+ return StringSet::New(isolate);
+ }
+
+ std::optional<DebugScriptScope> closure_scope =
+ closure_scope_info->scope_type() == FUNCTION_SCOPE
+ ? FindClosureScope(debug_scope_info, shared_info->StartPosition(),
+ shared_info->EndPosition(),
+ closure_scope_info->scope_type())
+ : DebugScriptScope::FromIndex(debug_scope_info, 0);
+ DCHECK(closure_scope.has_value());
+ if (!closure_scope.has_value()) {
+ return StringSet::New(isolate);
+ }
+
+ DirectHandle<ScopeInfo> current_scope_info = closure_scope_info;
+ Handle<StringSet> current_blocklist = StringSet::New(isolate);
+ Handle<StringSet> closure_blocklist;
+
+ for (std::optional<DebugScriptScope> scope = closure_scope; scope.has_value();
+ scope = scope->parent()) {
+ if (scope->scope_index() != closure_scope->scope_index() &&
+ scope->needs_context()) {
+ DCHECK(current_scope_info->HasOuterScopeInfo());
+ DirectHandle<ScopeInfo> next_scope_info(
+ current_scope_info->OuterScopeInfo(), isolate);
+ DCHECK_EQ(scope->unique_id_in_script(),
+ next_scope_info->UniqueIdInScript());
+ isolate->LocalsBlockListCacheSet(current_scope_info, next_scope_info,
+ current_blocklist);
+ if (closure_blocklist.is_null()) {
+ closure_blocklist = current_blocklist;
+ }
+ current_scope_info = next_scope_info;
+ current_blocklist = StringSet::New(isolate);
+ }
+
+ current_blocklist =
+ AddScopeStackLocalsToBlockList(isolate, current_blocklist, *scope);
+ }
+
+ DirectHandle<ScopeInfo> outer_scope_info =
+ current_scope_info->HasOuterScopeInfo()
+ ? direct_handle(current_scope_info->OuterScopeInfo(), isolate)
+ : DirectHandle<ScopeInfo>();
+ isolate->LocalsBlockListCacheSet(current_scope_info, outer_scope_info,
+ current_blocklist);
+ if (closure_blocklist.is_null()) {
+ closure_blocklist = current_blocklist;
+ }
+
+ return closure_blocklist;
+}
+
+Handle<StringSet> CalculateScopeBlockList(Isolate* isolate,
+ DebugScriptScope scope) {
+ Handle<StringSet> blocklist = StringSet::New(isolate);
+ for (std::optional<DebugScriptScope> current = scope;
+ current.has_value() && !current->needs_context();
+ current = current->parent()) {
+ blocklist = AddScopeStackLocalsToBlockList(isolate, blocklist, *current);
+ }
+ return blocklist;
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/debug/debug-block-list.h b/deps/v8/src/debug/debug-block-list.h
new file mode 100644
index 00000000000..00b349e6603
--- /dev/null
+++ b/deps/v8/src/debug/debug-block-list.h
@@ -0,0 +1,40 @@
+// Copyright 2026 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 V8_DEBUG_DEBUG_BLOCK_LIST_H_
+#define V8_DEBUG_DEBUG_BLOCK_LIST_H_
+
+#include "src/common/globals.h"
+#include "src/handles/handles.h"
+
+namespace v8 {
+namespace internal {
+
+class DebugScriptScope;
+class Isolate;
+class SharedFunctionInfo;
+class StringSet;
+
+// Ensures that the locals block-lists for `shared_info` and all its enclosing
+// context-allocating scopes within the script are calculated and stored in
+// `Isolate::locals_block_list_cache()`.
+//
+// Each scope `S` with a `ScopeInfo` receives a block-list (`StringSet`)
+// containing the names of all stack-allocated variables declared in `[S, K)`
+// (from `S` inclusive up to the next enclosing context-allocating scope `K`
+// exclusive). Returns the block-list for `shared_info->scope_info()`.
+V8_EXPORT_PRIVATE Handle<StringSet> EnsureLocalsBlockList(
+ Isolate* isolate, DirectHandle<SharedFunctionInfo> shared_info);
+
+// Calculates the block-list of stack-allocated variables declared in
+// `[scope, K)`, walking from `scope` (inclusive) up to the nearest enclosing
+// context-allocating scope `K` (exclusive). Used when evaluating in an outer
+// scope that does not have its own runtime `Context`.
+V8_EXPORT_PRIVATE Handle<StringSet> CalculateScopeBlockList(
+ Isolate* isolate, DebugScriptScope scope);
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_DEBUG_DEBUG_BLOCK_LIST_H_
diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc
index 654f7cca139..0ad55941094 100644
--- a/deps/v8/src/debug/debug-evaluate.cc
+++ b/deps/v8/src/debug/debug-evaluate.cc
@@ -11,6 +11,7 @@
#include "src/codegen/reloc-info.h"
#include "src/codegen/script-details.h"
#include "src/common/globals.h"
+#include "src/debug/debug-block-list.h"
#include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h"
#include "src/debug/debug.h"
@@ -148,8 +149,11 @@ MaybeDirectHandle<Object> DebugEvaluate::WithTopmostArguments(
// Materialize receiver.
DirectHandle<Object> this_value(it.frame()->receiver(), isolate);
- DCHECK_EQ(it.frame()->IsConstructor(), IsTheHole(*this_value));
- if (!IsTheHole(*this_value)) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*this_value));
+#endif
+ DCHECK_EQ(it.frame()->IsConstructor(), IsTdzHole(*this_value));
+ if (!IsTdzHole(*this_value)) {
DirectHandle<String> this_str = factory->this_string();
JSObject::SetOwnPropertyIgnoreAttributes(materialized, this_str, this_value,
NONE)
@@ -205,8 +209,7 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
int scope_index)
: isolate_(isolate),
frame_inspector_(frame, inlined_jsframe_index, isolate),
- scope_iterator_(isolate, &frame_inspector_,
- ScopeIterator::ReparseStrategy::kScriptIfNeeded),
+ scope_iterator_(isolate, &frame_inspector_),
scope_index_(scope_index) {
Factory* factory = isolate->factory();
@@ -232,8 +235,7 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
// variable names that are guaranteed to not be shadowed by stack-allocated
// variables. ScopeInfos between the function scope and the native
// context have a blocklist attached to implement that.
- // - The various block lists are calculated by the ScopeIterator during
- // iteration.
+ // - The various block lists are calculated by EnsureLocalsBlockList.
// Context::Lookup has special handling for debug-evaluate contexts:
// - Look up in the materialized stack variables.
// - Look up in the original context.
@@ -270,16 +272,13 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
if (first && !paused_scope_is_script_scope) {
// The DebugEvaluateContext we create for the closure scope is the only
// DebugEvaluateContext with a block list. This means we'll retrieve
- // the existing block list from the paused function scope
- // and also associate the temporary scope_info we create here with that
- // blocklist.
- DirectHandle<ScopeInfo> function_scope_info(
- frame_inspector_.GetFunction()->shared()->scope_info(), isolate_);
- DirectHandle<UnionOf<TheHole, StringSet>> block_list(
- isolate_->LocalsBlockListCacheGet(function_scope_info), isolate_);
- CHECK(IsStringSet(*block_list));
- isolate_->LocalsBlockListCacheSet(scope_info, Handle<ScopeInfo>::null(),
- Cast<StringSet>(block_list));
+ // the existing block list from the paused function scope (calculating
+ // it if needed) and also associate the temporary scope_info we create
+ // here with that blocklist.
+ Handle<StringSet> block_list =
+ EnsureLocalsBlockList(isolate_, outer_info());
+ isolate_->LocalsBlockListCacheSet(scope_info, DirectHandle<ScopeInfo>(),
+ block_list);
}
first = false;
@@ -289,16 +288,26 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
}
if (context_chain_.empty() && !IsNativeContext(*evaluation_context_)) {
- // When evaluating in an outer closure scope (!InInnerScope()),
- // context_chain_ is empty. We must still wrap evaluation_context_ in a
- // DebugEvaluateContext so that Context::Lookup sets
- // has_seen_debug_evaluate_context = true and consults the blocklist
- // stored in LocalsBlockListCache on outer closure contexts.
+ // When evaluating in an outer scope (!InInnerScope()), context_chain_ is
+ // empty. We must still wrap evaluation_context_ in a DebugEvaluateContext
+ // so that Context::Lookup sets has_seen_debug_evaluate_context = true and
+ // consults the blocklist stored in LocalsBlockListCache on outer contexts.
+ // If the target outer scope does not have its own runtime Context, we also
+ // calculate its [S_eval, K) blocklist on the fly and attach it to the
+ // synthetic scope_info.
+ EnsureLocalsBlockList(isolate_, outer_info());
scope_info = ScopeInfo::CreateForWithScope(isolate, scope_info);
scope_info->SetIsDebugEvaluateScope();
+ if (std::optional<DebugScriptScope> scope =
+ scope_iterator_.CurrentDebugScope();
+ scope.has_value() && !scope->needs_context()) {
+ Handle<StringSet> block_list = CalculateScopeBlockList(isolate_, *scope);
+ isolate_->LocalsBlockListCacheSet(scope_info, DirectHandle<ScopeInfo>(),
+ block_list);
+ }
evaluation_context_ = factory->NewDebugEvaluateContext(
evaluation_context_, scope_info, DirectHandle<JSReceiver>(),
- evaluation_context_);
+ DirectHandle<Context>());
}
}
@@ -548,9 +557,9 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
case Bytecode::kJumpLoop:
case Bytecode::kThrow:
case Bytecode::kReThrow:
- case Bytecode::kThrowReferenceErrorIfHole:
- case Bytecode::kThrowSuperNotCalledIfHole:
- case Bytecode::kThrowSuperAlreadyCalledIfNotHole:
+ case Bytecode::kThrowReferenceErrorIfTdzHole:
+ case Bytecode::kThrowSuperNotCalledIfTdzHole:
+ case Bytecode::kThrowSuperAlreadyCalledIfNotTdzHole:
case Bytecode::kIllegal:
case Bytecode::kCallJSRuntime:
case Bytecode::kReturn:
@@ -1334,6 +1343,7 @@ bool BytecodeRequiresRuntimeCheck(interpreter::Bytecode bytecode) {
switch (bytecode) {
case Bytecode::kSetNamedProperty:
case Bytecode::kDefineNamedOwnProperty:
+ case Bytecode::kDefineNamedOwnPropertyInLiteral:
case Bytecode::kSetKeyedProperty:
case Bytecode::kStaInArrayLiteral:
case Bytecode::kDefineKeyedOwnPropertyInLiteral:
diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h
index b63ecede773..83a4d79ac3a 100644
--- a/deps/v8/src/debug/debug-interface.h
+++ b/deps/v8/src/debug/debug-interface.h
@@ -492,6 +492,9 @@ class V8_EXPORT_PRIVATE ScopeIterator {
virtual bool HasLocationInfo() = 0;
virtual debug::Location GetStartLocation() = 0;
virtual debug::Location GetEndLocation() = 0;
+ // Whether the scope declares any variables (even if their values are not
+ // available). Scopes that don't are reported as empty.
+ virtual bool DeclaresLocals() = 0;
virtual bool SetVariableValue(v8::Local<v8::String> name,
v8::Local<v8::Value> value) = 0;
diff --git a/deps/v8/src/debug/debug-scope-info.cc b/deps/v8/src/debug/debug-scope-info.cc
index 84c7840540f..fcff84c47e0 100644
--- a/deps/v8/src/debug/debug-scope-info.cc
+++ b/deps/v8/src/debug/debug-scope-info.cc
@@ -42,20 +42,20 @@ namespace internal {
// | +0: int32_t start_position |
// | +4: int32_t end_position |
// | +8: int32_t parent_scope_index (-1 for root script scope) |
-// | +12: uint16_t flags (ScopeType, IsHidden, NeedsContext, HasSibling, etc)|
-// | +14: uint16_t var_count |
+// | +12: uint32_t flags (ScopeType, IsHidden, NeedsContext, HasSibling, etc)|
+// | +16: int32_t var_count |
// | --- Dynamic Optional Fields (present conditionally based on flags) --- |
-// | [+16: int32_t next_sibling_index] (if HasSiblingBit is set) |
+// | [+20: int32_t next_sibling_index] (if HasSiblingBit is set) |
// | [+..: int32_t context_id] (if NeedsContextBit is set) |
-// | [+..: uint16_t receiver_allocation_info] (if HasThisDeclBit is set) |
-// | [+..: uint16_t arguments_allocation_info] (if HasArgumentsBit is set) |
-// | [+..: uint16_t + int32_t function_var] (if HasFunctionVarBit is set)|
-// | --- Variables Array (var_count entries, 12 bytes each) --- |
+// | [+..: int32_t receiver_allocation_info] (if HasThisDeclBit is set) |
+// | [+..: int32_t arguments_allocation_info] (if HasArgumentsBit is set) |
+// | [+..: int32_t + int32_t function_var] (if HasFunctionVarBit is set)|
+// | --- Variables Array (var_count entries, 14 bytes each, packed) --- |
// | [DebugVariableEntry 0]: |
-// | +0: int16_t slot_index |
-// | +2: uint16_t location_mode_flags |
-// | +4: int32_t initializer_position |
-// | +8: int32_t name_index (into string_table FixedArray) |
+// | +0: int32_t slot_index |
+// | +4: uint16_t location_mode_flags |
+// | +6: int32_t initializer_position |
+// | +10: int32_t name_index (into string_table FixedArray) |
// | [DebugVariableEntry 1]... |
// +-------------------------------------------------------------------------+
// | Scope Record 1 (at scope_offsets[1])... |
@@ -67,17 +67,27 @@ struct ScopeRecord {
int32_t start_position;
int32_t end_position;
int32_t parent_scope_index;
- uint16_t flags;
- uint16_t var_count;
+ uint32_t flags;
+ // The number of declarations in a single scope is not bounded by anything
+ // the parser enforces, so this routinely exceeds 2^16 for generated code.
+ int32_t var_count;
};
static_assert(std::is_trivial_v<ScopeRecord>);
static_assert(std::is_standard_layout_v<ScopeRecord>);
// Ensure ScopeRecord has no padding. Update when adding new fields.
-static_assert(sizeof(ScopeRecord) == 16);
-
-struct DebugVariableEntry {
- int16_t slot_index;
+static_assert(sizeof(ScopeRecord) == 20);
+
+// Packed so that the entry stays 14 bytes instead of being padded to 16. The
+// struct is only ever read and written as a whole via
+// base::ReadUnalignedValue/base::WriteUnalignedValue, so the reduced alignment
+// is unobservable and no member address is ever taken.
+struct __attribute__((packed)) DebugVariableEntry {
+ // Variable::index(): a context slot, a stack slot or a parameter index.
+ // Context and stack slots grow with the scope's variable count and do
+ // exceed 2^16. Negative values are meaningful: -1 for unallocated variables
+ // and for the receiver, and module imports use negative indices.
+ int32_t slot_index;
uint16_t location_mode_flags;
int32_t initializer_position;
int32_t name_index;
@@ -85,14 +95,19 @@ struct DebugVariableEntry {
static_assert(std::is_trivial_v<DebugVariableEntry>);
static_assert(std::is_standard_layout_v<DebugVariableEntry>);
-static_assert(sizeof(DebugVariableEntry) == 12);
+static_assert(sizeof(DebugVariableEntry) == 14);
-using ScopeTypeBits = base::BitField<ScopeType, 0, 4, uint16_t>;
+// Note: These bits are stored in ScopeRecord::flags, which is 32 bits wide
+// because the 16 available bits were exhausted. Once ScopeIterator is fully
+// migrated onto DebugScriptScopeInfo some of these may turn out to be
+// redundant; revisit whether the word can shrink back to 16 bits then.
+using ScopeTypeBits = base::BitField<ScopeType, 0, 4, uint32_t>;
using HasChildrenBit = ScopeTypeBits::Next<bool, 1>;
using HasSiblingBit = HasChildrenBit::Next<bool, 1>;
using IsHiddenBit = HasSiblingBit::Next<bool, 1>;
using LanguageModeBit = IsHiddenBit::Next<LanguageMode, 1>;
-using IsArrowScopeBit = LanguageModeBit::Next<bool, 1>;
+using IsDeclarationScopeBit = LanguageModeBit::Next<bool, 1>;
+using IsArrowScopeBit = IsDeclarationScopeBit::Next<bool, 1>;
using HasThisDeclarationBit = IsArrowScopeBit::Next<bool, 1>;
using HasThisReferenceBit = HasThisDeclarationBit::Next<bool, 1>;
using HasSimpleParametersBit = HasThisReferenceBit::Next<bool, 1>;
@@ -100,7 +115,7 @@ using SloppyEvalCanExtendVarsBit = HasSimpleParametersBit::Next<bool, 1>;
using NeedsContextBit = SloppyEvalCanExtendVarsBit::Next<bool, 1>;
using HasArgumentsBit = NeedsContextBit::Next<bool, 1>;
using HasFunctionVarBit = HasArgumentsBit::Next<bool, 1>;
-static_assert(HasFunctionVarBit::kLastUsedBit < 16);
+static_assert(HasFunctionVarBit::kLastUsedBit < 32);
using VariableLocationBits = base::BitField<VariableLocation, 0, 4, uint16_t>;
using VariableModeBits = VariableLocationBits::Next<VariableMode, 4>;
@@ -109,26 +124,36 @@ using IsReceiverBit = IsSyntheticBit::Next<bool, 1>;
static_assert(IsReceiverBit::kLastUsedBit < 16);
// Encodes receiver, arguments, or function variable allocation info into a
-// 16-bit word:
+// 32-bit word:
// - Bits 0..1: VariableAllocationInfo (NONE, STACK, CONTEXT, UNUSED)
-// - Bits 2..15: 14-bit signed slot/parameter index
+// - Bits 2..31: 30-bit signed slot/parameter index
//
// In V8, stack-allocated receiver variables have parameter index -1 (allocated
-// via DeclarationScope::AllocateReceiver). Therefore, the 14-bit index field is
+// via DeclarationScope::AllocateReceiver). Therefore, the index field is
// treated as a signed two's-complement integer, requiring sign-extension upon
// decoding.
-uint16_t EncodeAllocInfo(VariableAllocationInfo info, int index) {
+//
+// A 16-bit word is not enough: context slot indices are only bounded by the
+// number of variables in the scope, and DeclarationScope::AllocateLocals()
+// deliberately allocates the function variable last, giving it the highest
+// index in its scope.
+constexpr int kAllocInfoIndexShift = 2;
+constexpr int kMaxAllocInfoIndex = (1 << 29) - 1;
+
+int32_t EncodeAllocInfo(VariableAllocationInfo info, int index) {
DCHECK_GE(index, -1);
- DCHECK_LE(index, 0x1FFF);
- uint16_t raw_index = static_cast<uint16_t>(index & 0x3FFF);
- return static_cast<uint16_t>(info) | (raw_index << 2);
+ // Deliberately a CHECK: silently truncating here would hand the debugger a
+ // plausible-looking but wrong slot index.
+ CHECK_LE(index, kMaxAllocInfoIndex);
+ return static_cast<int32_t>(
+ (static_cast<uint32_t>(index) << kAllocInfoIndexShift) |
+ static_cast<uint32_t>(info));
}
-std::pair<VariableAllocationInfo, int> DecodeAllocInfo(uint16_t val) {
- int raw_index = static_cast<int>(val >> 2);
- // Sign-extend 14-bit signed integer to int (e.g. 0x3FFF -> -1).
- if (raw_index & 0x2000) raw_index |= ~0x3FFF;
- return {static_cast<VariableAllocationInfo>(val & 3), raw_index};
+std::pair<VariableAllocationInfo, int> DecodeAllocInfo(int32_t val) {
+ // C++20 guarantees an arithmetic (sign-extending) shift for signed types.
+ return {static_cast<VariableAllocationInfo>(val & 3),
+ val >> kAllocInfoIndexShift};
}
int32_t GetScopeCount(Tagged<DebugScriptScopeInfo> info) {
@@ -168,7 +193,7 @@ const uint8_t* DebugScriptScope::payload() const {
return info_->numeric_data()->begin() + offset_;
}
-uint16_t DebugScriptScope::flags() const {
+uint32_t DebugScriptScope::flags() const {
return base::ReadUnalignedValue<ScopeRecord>(payload()).flags;
}
@@ -206,6 +231,27 @@ int DebugScriptScope::end_position() const {
return base::ReadUnalignedValue<ScopeRecord>(payload()).end_position;
}
+bool DebugScriptScope::ContainsPosition(int position,
+ bool is_closure_found) const {
+ // In case the closure scope hasn't been found yet, we are less strict about
+ // recursing downwards. This might be the case for nested arrow functions
+ // that have the same end position.
+ const bool position_fits_end =
+ is_closure_found ? position < end_position() : position <= end_position();
+ // While we're evaluating a class, the calling function will have a class
+ // context on the stack with a range that starts at Token::kClass, and the
+ // source position will also point to Token::kClass. To identify the matching
+ // scope we include start in the accepted range for class scopes.
+ //
+ // Similarly "with" scopes can already have bytecodes where the source
+ // position points to the closing parenthesis with the "with" context
+ // already pushed.
+ const bool position_fits_start = is_class_scope() || is_with_scope()
+ ? start_position() <= position
+ : start_position() < position;
+ return position_fits_start && position_fits_end;
+}
+
int DebugScriptScope::parent_index() const {
return base::ReadUnalignedValue<ScopeRecord>(payload()).parent_scope_index;
}
@@ -229,9 +275,7 @@ bool DebugScriptScope::is_block_scope() const {
}
bool DebugScriptScope::is_declaration_scope() const {
- return is_script_scope() || is_function_scope() ||
- scope_type() == ScopeType::MODULE_SCOPE ||
- scope_type() == ScopeType::EVAL_SCOPE;
+ return IsDeclarationScopeBit::decode(flags());
}
LanguageMode DebugScriptScope::language_mode() const {
@@ -314,17 +358,17 @@ size_t DebugScriptScope::receiver_info_offset() const {
size_t DebugScriptScope::arguments_info_offset() const {
return receiver_info_offset() +
- (HasThisDeclarationBit::decode(flags()) ? kUInt16Size : 0);
+ (HasThisDeclarationBit::decode(flags()) ? kInt32Size : 0);
}
size_t DebugScriptScope::function_variable_offset() const {
return arguments_info_offset() +
- (HasArgumentsBit::decode(flags()) ? kUInt16Size : 0);
+ (HasArgumentsBit::decode(flags()) ? kInt32Size : 0);
}
size_t DebugScriptScope::variables_offset() const {
return function_variable_offset() +
- (HasFunctionVarBit::decode(flags()) ? (kUInt16Size + kInt32Size) : 0);
+ (HasFunctionVarBit::decode(flags()) ? (2 * kInt32Size) : 0);
}
size_t DebugScriptScope::record_size() const {
@@ -339,14 +383,14 @@ int DebugScriptScope::unique_id_in_script() const {
std::pair<VariableAllocationInfo, int> DebugScriptScope::receiver_info() const {
if (!has_this_declaration()) return {VariableAllocationInfo::NONE, -1};
return DecodeAllocInfo(
- base::ReadUnalignedValue<uint16_t>(payload() + receiver_info_offset()));
+ base::ReadUnalignedValue<int32_t>(payload() + receiver_info_offset()));
}
std::pair<VariableAllocationInfo, int> DebugScriptScope::arguments_info()
const {
if (!has_arguments()) return {VariableAllocationInfo::NONE, -1};
return DecodeAllocInfo(
- base::ReadUnalignedValue<uint16_t>(payload() + arguments_info_offset()));
+ base::ReadUnalignedValue<int32_t>(payload() + arguments_info_offset()));
}
const uint8_t* DebugScriptScope::function_variable_payload() const {
@@ -358,17 +402,18 @@ std::pair<VariableAllocationInfo, int>
DebugScriptScope::function_variable_info() const {
const uint8_t* ptr = function_variable_payload();
if (!ptr) return {VariableAllocationInfo::NONE, -1};
- return DecodeAllocInfo(base::ReadUnalignedValue<uint16_t>(ptr));
+ return DecodeAllocInfo(base::ReadUnalignedValue<int32_t>(ptr));
}
-Tagged<String> DebugScriptScope::function_variable_name() const {
+Tagged<InternalizedString> DebugScriptScope::function_variable_name() const {
const uint8_t* ptr = function_variable_payload();
if (!ptr) return {};
- int32_t name_index = base::ReadUnalignedValue<int32_t>(ptr + kUInt16Size);
- DCHECK_GE(name_index, 0);
- DCHECK_LT(static_cast<uint32_t>(name_index),
- info_->string_table()->length().value());
- return Cast<String>(info_->string_table()->get(name_index));
+ int32_t name_index = base::ReadUnalignedValue<int32_t>(ptr + kInt32Size);
+ CHECK_GE(name_index, 0);
+ CHECK_LT(static_cast<uint32_t>(name_index),
+ info_->string_table()->length().value());
+ return CheckedCast<InternalizedString>(
+ info_->string_table()->get(name_index));
}
int DebugScriptScope::variable_count() const {
@@ -386,12 +431,11 @@ DebugVariableInfo DebugScriptScope::variable(int index) const {
variables_payload() + index * sizeof(DebugVariableEntry);
DebugVariableEntry entry =
base::ReadUnalignedValue<DebugVariableEntry>(entry_ptr);
- Tagged<String> name;
- if (entry.name_index >= 0) {
- DCHECK_LT(static_cast<uint32_t>(entry.name_index),
- info_->string_table()->length().value());
- name = Cast<String>(info_->string_table()->get(entry.name_index));
- }
+ CHECK_GE(entry.name_index, 0);
+ CHECK_LT(static_cast<uint32_t>(entry.name_index),
+ info_->string_table()->length().value());
+ Tagged<InternalizedString> name = CheckedCast<InternalizedString>(
+ info_->string_table()->get(entry.name_index));
return DebugVariableInfo{
.name = name,
.location = VariableLocationBits::decode(entry.location_mode_flags),
@@ -413,7 +457,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
ZoneAbslFlatHashMap<const AstRawString*, int32_t> string_map(zone);
auto get_or_insert_string = [&](const AstRawString* raw_name) -> int32_t {
- if (raw_name == nullptr) return -1;
+ CHECK_NOT_NULL(raw_name);
auto it = string_map.find(raw_name);
if (it != string_map.end()) return it->second;
int32_t index = base::checked_cast<int32_t>(string_table.size());
@@ -461,17 +505,17 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
}
if (all_scopes[i]->is_declaration_scope() &&
all_scopes[i]->AsDeclarationScope()->has_this_declaration()) {
- total_size += kUInt16Size;
+ total_size += kInt32Size;
}
if (all_scopes[i]->is_declaration_scope() &&
all_scopes[i]->AsDeclarationScope()->arguments() != nullptr) {
- total_size += kUInt16Size;
+ total_size += kInt32Size;
}
if (all_scopes[i]->is_declaration_scope() &&
all_scopes[i]->AsDeclarationScope()->function_var() != nullptr) {
- total_size += kUInt16Size + kInt32Size;
+ total_size += 2 * kInt32Size;
}
- uint16_t var_count = base::checked_cast<uint16_t>(std::distance(
+ int32_t var_count = base::checked_cast<int32_t>(std::distance(
all_scopes[i]->locals()->begin(), all_scopes[i]->locals()->end()));
total_size += var_count * sizeof(DebugVariableEntry);
}
@@ -500,12 +544,13 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
bool has_arguments = false;
bool has_function_var = false;
- uint16_t flags = 0;
+ uint32_t flags = 0;
flags = ScopeTypeBits::update(flags, scope->scope_type());
flags = HasChildrenBit::update(flags, scope->inner_scope() != nullptr);
flags = HasSiblingBit::update(flags, has_sibling);
flags = IsHiddenBit::update(flags, scope->is_hidden());
flags = LanguageModeBit::update(flags, scope->language_mode());
+ flags = IsDeclarationScopeBit::update(flags, scope->is_declaration_scope());
flags = HasThisReferenceBit::update(flags, scope->HasThisReference());
flags = NeedsContextBit::update(flags, needs_context);
if (scope->is_declaration_scope()) {
@@ -523,7 +568,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
flags = HasArgumentsBit::update(flags, has_arguments);
flags = HasFunctionVarBit::update(flags, has_function_var);
- uint16_t var_count = base::checked_cast<uint16_t>(
+ int32_t var_count = base::checked_cast<int32_t>(
std::distance(scope->locals()->begin(), scope->locals()->end()));
int32_t parent_scope_index = find_scope_index(scope->outer_scope());
@@ -553,7 +598,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
? VariableAllocationInfo::CONTEXT
: VariableAllocationInfo::STACK;
- writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ writer.Write<int32_t>(EncodeAllocInfo(info, var->index()));
}
if (has_arguments) {
Variable* var = scope->AsDeclarationScope()->arguments();
@@ -561,7 +606,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
? VariableAllocationInfo::CONTEXT
: VariableAllocationInfo::STACK;
- writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ writer.Write<int32_t>(EncodeAllocInfo(info, var->index()));
}
if (has_function_var) {
Variable* var = scope->AsDeclarationScope()->function_var();
@@ -569,7 +614,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
? VariableAllocationInfo::CONTEXT
: VariableAllocationInfo::STACK;
- writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ writer.Write<int32_t>(EncodeAllocInfo(info, var->index()));
int32_t name_index = get_or_insert_string(var->raw_name());
writer.Write<int32_t>(name_index);
}
@@ -602,7 +647,7 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
var_flags = IsReceiverBit::update(var_flags, is_receiver);
writer.Write<DebugVariableEntry>(DebugVariableEntry{
- .slot_index = base::checked_cast<int16_t>(var->index()),
+ .slot_index = var->index(),
.location_mode_flags = var_flags,
.initializer_position = var->initializer_position(),
.name_index = get_or_insert_string(var->raw_name()),
@@ -622,7 +667,9 @@ Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
Handle<FixedArray> table =
isolate->factory()->NewFixedArray(string_count, AllocationType::kOld);
for (uint32_t i = 0; i < string_count; ++i) {
- table->set(i, *string_table[i]->string());
+ DirectHandle<InternalizedString> str = string_table[i]->string();
+ CHECK(IsInternalizedString(*str));
+ table->set(i, *str);
}
final_string_table = table;
}
@@ -676,6 +723,57 @@ Handle<DebugScriptScopeInfo> EnsureDebugScriptScopeInfo(
return debug_info;
}
+int DebugScriptScopeCount(Tagged<DebugScriptScopeInfo> info) {
+ return GetScopeCount(info);
+}
+
+std::optional<DebugScriptScope> FindClosureScope(
+ DirectHandle<DebugScriptScopeInfo> info, int start_position,
+ int end_position, ScopeType scope_type) {
+ // SerializeDebugScriptScopeInfo() emits scopes in DFS pre-order, so scanning
+ // the offset table linearly visits the scopes in the same order the AST
+ // traversal did.
+ const int scope_count = DebugScriptScopeCount(*info);
+ for (int i = 0; i < scope_count; ++i) {
+ DebugScriptScope scope = DebugScriptScope::FromIndex(info, i);
+ if (scope.scope_type() == scope_type &&
+ scope.start_position() == start_position &&
+ scope.end_position() == end_position) {
+ return scope;
+ }
+ }
+ return std::nullopt;
+}
+
+namespace {
+
+// Visits all descendants of `scope` and narrows `*best` down to the scope with
+// the tightest bounds around `position`.
+void NarrowToInnermostScope(DebugScriptScope scope, int position,
+ DebugScriptScope* best) {
+ for (std::optional<DebugScriptScope> child = scope.first_child();
+ child.has_value(); child = child->next_sibling()) {
+ // Update `*best` if `child` contains `position` and is a tighter fit than
+ // the currently best scope. Generators have the same source position as
+ // the scope they belong to, so we also check for equality.
+ if (child->ContainsPosition(position, /*is_closure_found=*/true) &&
+ child->start_position() >= best->start_position() &&
+ child->end_position() <= best->end_position()) {
+ *best = *child;
+ }
+ NarrowToInnermostScope(*child, position, best);
+ }
+}
+
+} // namespace
+
+DebugScriptScope FindInnermostScope(DebugScriptScope closure_scope,
+ int position) {
+ DebugScriptScope best = closure_scope;
+ NarrowToInnermostScope(closure_scope, position, &best);
+ return best;
+}
+
#ifdef VERIFY_HEAP
// DebugScriptScopeInfo::DebugScriptScopeInfoVerify is placed here instead of in
// objects-debug.cc to keep the exact layout of numeric_data local to
@@ -713,6 +811,19 @@ void DebugScriptScopeInfo::DebugScriptScopeInfoVerify(Isolate* isolate) {
CHECK_LE(offset + record_size,
static_cast<size_t>(bytes->length().value()));
+ // Top-level and function scopes are always declaration scopes. Block
+ // scopes may or may not be (see IsDeclarationScopeBit).
+ CHECK_IMPLIES(scope.is_script_scope() || scope.is_function_scope() ||
+ scope.is_module_scope() || scope.is_eval_scope(),
+ scope.is_declaration_scope());
+ // The declaration-only flags must be clear for non-declaration scopes.
+ CHECK_IMPLIES(!scope.is_declaration_scope(),
+ !scope.is_arrow_scope() && !scope.has_this_declaration() &&
+ !scope.has_simple_parameters() &&
+ !scope.has_arguments() &&
+ !scope.has_function_variable() &&
+ !scope.sloppy_eval_can_extend_vars());
+
if (scope.needs_context()) {
CHECK_GE(scope.unique_id_in_script(), -2);
} else {
@@ -737,20 +848,19 @@ void DebugScriptScopeInfo::DebugScriptScopeInfoVerify(Isolate* isolate) {
CHECK(!scope.function_variable_name().is_null());
const uint8_t* ptr = scope.function_variable_payload();
CHECK_NOT_NULL(ptr);
- int32_t name_index = base::ReadUnalignedValue<int32_t>(ptr + kUInt16Size);
+ int32_t name_index = base::ReadUnalignedValue<int32_t>(ptr + kInt32Size);
CHECK_GE(name_index, 0);
CHECK_LT(static_cast<uint32_t>(name_index),
string_table()->length().value());
- CHECK(IsString(string_table()->get(name_index)));
+ CHECK(IsInternalizedString(string_table()->get(name_index)));
}
CHECK_EQ(scope.variable_count(),
base::ReadUnalignedValue<ScopeRecord>(scope.payload()).var_count);
for (int v = 0; v < scope.variable_count(); ++v) {
DebugVariableInfo var = scope.variable(v);
- if (!var.name.is_null()) {
- CHECK(IsString(var.name));
- }
+ CHECK(!var.name.is_null());
+ CHECK(IsInternalizedString(var.name));
}
if (i == 0) {
diff --git a/deps/v8/src/debug/debug-scope-info.h b/deps/v8/src/debug/debug-scope-info.h
index cbf6313a478..b34627e8c00 100644
--- a/deps/v8/src/debug/debug-scope-info.h
+++ b/deps/v8/src/debug/debug-scope-info.h
@@ -17,19 +17,27 @@ namespace v8 {
namespace internal {
class DeclarationScope;
+class InternalizedString;
class Isolate;
class Script;
-class String;
// Structure holding deserialized variable information for debugger inspection.
struct DebugVariableInfo {
- Tagged<String> name;
+ Tagged<InternalizedString> name;
VariableLocation location;
int index;
VariableMode mode;
int initializer_position;
bool is_synthetic;
bool is_receiver;
+
+ // LINT.IfChange(VariableIsExport)
+ bool is_export() const {
+ DCHECK_EQ(location, VariableLocation::MODULE);
+ DCHECK_NE(index, 0);
+ return index > 0;
+ }
+ // LINT.ThenChange(/src/ast/variables.h:VariableIsExport)
};
// Stack-allocated cursor for navigating and querying serialized scope trees
@@ -53,6 +61,14 @@ class V8_EXPORT_PRIVATE DebugScriptScope {
ScopeType scope_type() const;
LanguageMode language_mode() const;
+ // Returns true if `position` lies within this scope.
+ //
+ // `is_closure_found` controls how strict we are about the end position:
+ // while the closure scope hasn't been determined yet we also accept
+ // `position == end_position()`, since nested arrow functions can share their
+ // end position with the function they are embedded in.
+ bool ContainsPosition(int position, bool is_closure_found) const;
+
// Scope Predicates
bool is_script_scope() const;
bool is_function_scope() const;
@@ -87,7 +103,7 @@ class V8_EXPORT_PRIVATE DebugScriptScope {
// arguments variable (or -1 if none/unallocated).
std::pair<VariableAllocationInfo, int> arguments_info() const;
std::pair<VariableAllocationInfo, int> function_variable_info() const;
- Tagged<String> function_variable_name() const;
+ Tagged<InternalizedString> function_variable_name() const;
// Local Variables Info
int variable_count() const;
@@ -101,7 +117,7 @@ class V8_EXPORT_PRIVATE DebugScriptScope {
const uint8_t* payload() const;
const uint8_t* function_variable_payload() const;
const uint8_t* variables_payload() const;
- uint16_t flags() const;
+ uint32_t flags() const;
int parent_index() const;
// Chained offset calculation methods (private to DebugScriptScope).
@@ -134,6 +150,30 @@ V8_EXPORT_PRIVATE Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
V8_EXPORT_PRIVATE Handle<DebugScriptScopeInfo> EnsureDebugScriptScopeInfo(
Isolate* isolate, DirectHandle<Script> script);
+// Returns the number of scopes serialized in `info`.
+V8_EXPORT_PRIVATE int DebugScriptScopeCount(Tagged<DebugScriptScopeInfo> info);
+
+// Returns the scope that exactly matches the extent of the function described
+// by `start_position`, `end_position` and `scope_type`, or nullopt if `info`
+// doesn't contain such a scope.
+//
+// Matching the positions alone is not enough: scopes can share their exact
+// extent with a scope of a different type. A class declaration that spans the
+// whole script for example has the same positions as the script scope.
+V8_EXPORT_PRIVATE std::optional<DebugScriptScope> FindClosureScope(
+ DirectHandle<DebugScriptScopeInfo> info, int start_position,
+ int end_position, ScopeType scope_type);
+
+// Returns the innermost scope around `position` at or below `closure_scope`,
+// i.e. the scope a debugger paused at `position` starts iterating from.
+//
+// V8's scope tree doesn't guarantee that siblings don't overlap, so all
+// descendants of `closure_scope` are considered and the one with the tightest
+// bounds around `position` wins. `closure_scope` itself is returned if no
+// descendant is a better fit.
+V8_EXPORT_PRIVATE DebugScriptScope
+FindInnermostScope(DebugScriptScope closure_scope, int position);
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/debug/debug-scope-iterator.cc b/deps/v8/src/debug/debug-scope-iterator.cc
index cd834f2954e..8e2e30d745c 100644
--- a/deps/v8/src/debug/debug-scope-iterator.cc
+++ b/deps/v8/src/debug/debug-scope-iterator.cc
@@ -42,9 +42,7 @@ namespace internal {
DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
FrameInspector* frame_inspector)
- : iterator_(
- isolate, frame_inspector,
- ::v8::internal::ScopeIterator::ReparseStrategy::kFunctionLiteral) {
+ : iterator_(isolate, frame_inspector) {
iterator_.AdvanceToScopeNumber(0);
}
@@ -68,8 +66,6 @@ void DebugScopeIterator::Advance() {
iterator_.AdvanceToScopeNumber(0);
}
-bool DebugScopeIterator::ShouldIgnore() { return iterator_.ShouldIgnore(); }
-
v8::debug::ScopeIterator::ScopeType DebugScopeIterator::GetType() {
DCHECK(!Done());
return static_cast<v8::debug::ScopeIterator::ScopeType>(iterator_.Type());
@@ -109,6 +105,11 @@ debug::Location DebugScopeIterator::GetEndLocation() {
->GetSourceLocation(iterator_.end_position());
}
+bool DebugScopeIterator::DeclaresLocals() {
+ DCHECK(!Done());
+ return iterator_.DeclaresLocals(i::ScopeIterator::Mode::ALL);
+}
+
bool DebugScopeIterator::SetVariableValue(v8::Local<v8::String> name,
v8::Local<v8::Value> value) {
DCHECK(!Done());
diff --git a/deps/v8/src/debug/debug-scope-iterator.h b/deps/v8/src/debug/debug-scope-iterator.h
index 33ed43fc0a0..8a3d0d1c7c0 100644
--- a/deps/v8/src/debug/debug-scope-iterator.h
+++ b/deps/v8/src/debug/debug-scope-iterator.h
@@ -27,13 +27,12 @@ class DebugScopeIterator final : public debug::ScopeIterator {
bool HasLocationInfo() override;
debug::Location GetStartLocation() override;
debug::Location GetEndLocation() override;
+ bool DeclaresLocals() override;
bool SetVariableValue(v8::Local<v8::String> name,
v8::Local<v8::Value> value) override;
private:
- bool ShouldIgnore();
-
v8::internal::ScopeIterator iterator_;
};
diff --git a/deps/v8/src/debug/debug-scopes.cc b/deps/v8/src/debug/debug-scopes.cc
index 365489da889..efb79220047 100644
--- a/deps/v8/src/debug/debug-scopes.cc
+++ b/deps/v8/src/debug/debug-scopes.cc
@@ -5,29 +5,25 @@
#include "src/debug/debug-scopes.h"
#include <algorithm>
-#include <memory>
+#include <optional>
-#include "src/ast/ast.h"
-#include "src/ast/scopes.h"
+#include "src/ast/modules.h"
+#include "src/debug/debug-scope-info.h"
#include "src/debug/debug.h"
#include "src/execution/frames-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/source-text-module.h"
#include "src/objects/string-set.h"
-#include "src/parsing/parse-info.h"
-#include "src/parsing/parsing.h"
#include "src/utils/ostreams.h"
namespace v8 {
namespace internal {
-ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
- ReparseStrategy strategy)
+ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector)
: isolate_(isolate),
frame_inspector_(frame_inspector),
function_(frame_inspector_->GetFunction()),
- script_(frame_inspector_->GetScript()),
- locals_(StringSet::New(isolate)) {
+ script_(frame_inspector_->GetScript()) {
if (!IsContext(*frame_inspector->GetContext())) {
// Optimized frame, context or function cannot be materialized. Give up.
return;
@@ -39,7 +35,7 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
DCHECK_NE(Script::Type::kWasm, frame_inspector->GetScript()->type());
#endif // V8_ENABLE_WEBASSEMBLY
- TryParseAndRetrieveScopes(strategy);
+ TryParseAndRetrieveScopes();
}
ScopeIterator::~ScopeIterator() = default;
@@ -61,9 +57,7 @@ DirectHandle<Object> ScopeIterator::GetFunctionDebugName() const {
ScopeIterator::ScopeIterator(Isolate* isolate,
DirectHandle<JSFunction> function)
- : isolate_(isolate),
- context_(function->context(), isolate),
- locals_(StringSet::New(isolate)) {
+ : isolate_(isolate), context_(function->context(), isolate) {
if (!function->shared()->IsSubjectToDebugging()) {
context_ = Handle<Context>();
return;
@@ -78,154 +72,27 @@ ScopeIterator::ScopeIterator(Isolate* isolate,
generator_(generator),
function_(generator->function(), isolate),
context_(generator->context(), isolate),
- script_(Cast<Script>(function_->shared()->script()), isolate),
- locals_(StringSet::New(isolate)) {
+ script_(Cast<Script>(function_->shared()->script()), isolate) {
CHECK(function_->shared()->IsSubjectToDebugging());
- TryParseAndRetrieveScopes(ReparseStrategy::kFunctionLiteral);
+ TryParseAndRetrieveScopes();
}
void ScopeIterator::Restart() {
DCHECK_NOT_NULL(frame_inspector_);
function_ = frame_inspector_->GetFunction();
context_ = Cast<Context>(frame_inspector_->GetContext());
- current_scope_ = start_scope_;
- DCHECK_NOT_NULL(current_scope_);
+ current_scope_index_ = start_scope_index_;
+ DCHECK_NE(current_scope_index_, -1);
UnwrapEvaluationContext();
seen_script_scope_ = false;
- calculate_blocklists_ = false;
}
-namespace {
-
-// Takes the scope of a parsed script, a function and a break location
-// inside the function. The result is the innermost lexical scope around
-// the break point, which serves as the starting point of the ScopeIterator.
-// And the scope of the function that was passed in (called closure scope).
-//
-// The start scope is guaranteed to be either the closure scope itself,
-// or a child of the closure scope.
-class ScopeChainRetriever {
- public:
- ScopeChainRetriever(DeclarationScope* scope,
- DirectHandle<JSFunction> function, int position)
- : scope_(scope),
- break_scope_start_(function->shared()->StartPosition()),
- break_scope_end_(function->shared()->EndPosition()),
- break_scope_type_(function->shared()->scope_info()->scope_type()),
- position_(position) {
- DCHECK_NOT_NULL(scope);
- RetrieveScopes();
- }
-
- DeclarationScope* ClosureScope() { return closure_scope_; }
- Scope* StartScope() { return start_scope_; }
-
- private:
- DeclarationScope* scope_;
- const int break_scope_start_;
- const int break_scope_end_;
- const ScopeType break_scope_type_;
- const int position_;
-
- DeclarationScope* closure_scope_ = nullptr;
- Scope* start_scope_ = nullptr;
-
- void RetrieveScopes() {
- // 1. Find the closure scope with a DFS.
- RetrieveClosureScope(scope_);
- DCHECK_NOT_NULL(closure_scope_);
-
- // 2. Starting from the closure scope search inwards. Given that V8's scope
- // tree doesn't guarantee that siblings don't overlap, we look at all
- // scopes and pick the one with the tightest bounds around `position_`.
- start_scope_ = closure_scope_;
- RetrieveStartScope(closure_scope_);
- DCHECK_NOT_NULL(start_scope_);
- }
-
- bool RetrieveClosureScope(Scope* scope) {
- // The closure scope is the scope that matches exactly the function we
- // paused in.
- // Note that comparing the position alone is not enough and we also need to
- // match the scope type. E.g. class member initializer have the exact same
- // scope positions as their class scope.
- if (break_scope_type_ == scope->scope_type() &&
- break_scope_start_ == scope->start_position() &&
- break_scope_end_ == scope->end_position()) {
- closure_scope_ = scope->AsDeclarationScope();
- return true;
- }
-
- for (Scope* inner_scope = scope->inner_scope(); inner_scope != nullptr;
- inner_scope = inner_scope->sibling()) {
- if (RetrieveClosureScope(inner_scope)) return true;
- }
- return false;
- }
-
- void RetrieveStartScope(Scope* scope) {
- const int start = scope->start_position();
- const int end = scope->end_position();
-
- // Update start_scope_ if scope contains `position_` and scope is a tighter
- // fit than the currently set start_scope_.
- // Generators have the same source position so we also check for equality.
- if (ContainsPosition(scope) && start >= start_scope_->start_position() &&
- end <= start_scope_->end_position()) {
- start_scope_ = scope;
- }
-
- for (Scope* inner_scope = scope->inner_scope(); inner_scope != nullptr;
- inner_scope = inner_scope->sibling()) {
- RetrieveStartScope(inner_scope);
- }
- }
-
- bool ContainsPosition(Scope* scope) {
- const int start = scope->start_position();
- const int end = scope->end_position();
- // In case the closure_scope_ hasn't been found yet, we are less strict
- // about recursing downwards. This might be the case for nested arrow
- // functions that have the same end position.
- const bool position_fits_end =
- closure_scope_ ? position_ < end : position_ <= end;
- // While we're evaluating a class, the calling function will have a class
- // context on the stack with a range that starts at Token::kClass, and the
- // source position will also point to Token::kClass. To identify the
- // matching scope we include start in the accepted range for class scopes.
- //
- // Similarly "with" scopes can already have bytecodes where the source
- // position points to the closing parenthesis with the "with" context
- // already pushed.
- const bool position_fits_start =
- scope->is_class_scope() || scope->is_with_scope() ? start <= position_
- : start < position_;
- return position_fits_start && position_fits_end;
- }
-};
-
-// Walks a ScopeInfo outwards until it finds a EVAL scope.
-MaybeDirectHandle<ScopeInfo> FindEvalScope(Isolate* isolate,
- Tagged<ScopeInfo> start_scope) {
- Tagged<ScopeInfo> scope = start_scope;
- while (scope->scope_type() != ScopeType::EVAL_SCOPE &&
- scope->HasOuterScopeInfo()) {
- scope = scope->OuterScopeInfo();
- }
-
- return scope->scope_type() == ScopeType::EVAL_SCOPE
- ? MaybeHandle<ScopeInfo>(scope, isolate)
- : kNullMaybeHandle;
-}
-
-} // namespace
-
-void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
+void ScopeIterator::TryParseAndRetrieveScopes() {
// Catch the case when the debugger stops in an internal function.
DirectHandle<SharedFunctionInfo> shared_info(function_->shared(), isolate_);
DirectHandle<ScopeInfo> scope_info(shared_info->scope_info(), isolate_);
if (IsUndefined(shared_info->script())) {
- current_scope_ = closure_scope_ = nullptr;
+ current_scope_index_ = closure_scope_index_ = start_scope_index_ = -1;
context_ = handle(function_->context(), isolate_);
function_ = Handle<JSFunction>();
return;
@@ -247,119 +114,48 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
ignore_nested_scopes = location.IsReturn();
}
- if (strategy == ReparseStrategy::kScriptIfNeeded) {
- Tagged<UnionOf<TheHole, StringSet>> maybe_block_list =
- isolate_->LocalsBlockListCacheGet(scope_info);
- calculate_blocklists_ = IsTheHole(maybe_block_list);
- strategy = calculate_blocklists_ ? ReparseStrategy::kScriptIfNeeded
- : ReparseStrategy::kFunctionLiteral;
- }
-
- // Reparse the code and analyze the scopes.
- // Depending on the chosen strategy, the whole script or just
- // the closure is re-parsed for function scopes.
DirectHandle<Script> script(Cast<Script>(shared_info->script()), isolate_);
-
- // Pick between flags for a single function compilation, or an eager
- // compilation of the whole script.
- UnoptimizedCompileFlags flags =
- (scope_info->scope_type() == FUNCTION_SCOPE &&
- strategy == ReparseStrategy::kFunctionLiteral)
- ? UnoptimizedCompileFlags::ForFunctionCompile(isolate_, *shared_info)
- : UnoptimizedCompileFlags::ForScriptCompile(isolate_, *script)
- .set_is_eager(true);
- flags.set_is_reparse(true);
-
- MaybeDirectHandle<ScopeInfo> maybe_outer_scope;
- if (flags.is_toplevel() && script->is_eval()) {
- // Re-parsing a full eval script requires us to correctly set the outer
- // language mode and potentially an outer scope info.
- //
- // We walk the runtime scope chain and look for an EVAL scope. If we don't
- // find one, we assume sloppy mode and no outer scope info.
-
- DCHECK(flags.is_eval());
-
- DirectHandle<ScopeInfo> eval_scope;
- if (FindEvalScope(isolate_, *scope_info).ToHandle(&eval_scope)) {
- flags.set_outer_language_mode(eval_scope->language_mode());
- if (eval_scope->HasOuterScopeInfo()) {
- maybe_outer_scope =
- direct_handle(eval_scope->OuterScopeInfo(), isolate_);
- }
- } else {
- DCHECK_EQ(flags.outer_language_mode(), LanguageMode::kSloppy);
- DCHECK(maybe_outer_scope.is_null());
- }
- } else if (scope_info->scope_type() == EVAL_SCOPE || script->is_wrapped()) {
- flags.set_is_eval(true);
- if (!IsNativeContext(*context_)) {
- maybe_outer_scope = direct_handle(context_->scope_info(), isolate_);
- }
- // Language mode may be inherited from the eval caller.
- // Retrieve it from shared function info.
- flags.set_outer_language_mode(shared_info->language_mode());
- } else if (scope_info->scope_type() == MODULE_SCOPE) {
- DCHECK(script->origin_options().IsModule());
- DCHECK(flags.is_module());
- } else {
- DCHECK(scope_info->is_script_scope() ||
- scope_info->scope_type() == FUNCTION_SCOPE);
- }
-
- UnoptimizedCompileState compile_state;
-
- reusable_compile_state_ =
- std::make_unique<ReusableUnoptimizedCompileState>(isolate_);
- info_ = std::make_unique<ParseInfo>(isolate_, flags, &compile_state,
- reusable_compile_state_.get());
-
- const bool parse_result =
- flags.is_toplevel()
- ? parsing::ParseProgram(info_.get(), script, maybe_outer_scope,
- isolate_,
- parsing::ReportStatisticsMode{false})
- : parsing::ParseFunction(info_.get(), shared_info, isolate_,
- parsing::ReportStatisticsMode{false});
-
- if (parse_result) {
- DeclarationScope* literal_scope = info_->literal()->scope();
-
- ScopeChainRetriever scope_chain_retriever(literal_scope, function_,
- GetSourcePosition());
- start_scope_ = scope_chain_retriever.StartScope();
- current_scope_ = start_scope_;
-
- // In case of a FUNCTION_SCOPE, the ScopeIterator expects
- // {closure_scope_} to be set to the scope of the function.
- closure_scope_ = scope_info->scope_type() == FUNCTION_SCOPE
- ? scope_chain_retriever.ClosureScope()
- : literal_scope;
-
- if (ignore_nested_scopes) {
- current_scope_ = closure_scope_;
- start_scope_ = current_scope_;
- // ignore_nested_scopes is only used for the return-position breakpoint,
- // so we can safely assume that the closure context for the current
- // function exists if it needs one.
- if (closure_scope_->NeedsContext()) {
- context_ = handle(context_->closure_context(), isolate_);
- }
- }
-
- MaybeCollectAndStoreLocalBlocklists();
- UnwrapEvaluationContext();
- } else {
+ debug_scope_info_ = EnsureDebugScriptScopeInfo(isolate_, script);
+ if (debug_scope_info_.is_null()) {
// A failed reparse indicates that the preparser has diverged from the
// parser, that the preparse data given to the initial parse was faulty, or
// a stack overflow.
- // TODO(leszeks): This error is pretty unexpected, so we could report the
- // error in debug mode. Better to not fail in release though, in case it's
- // just a stack overflow.
-
// Silently fail by presenting an empty context chain.
context_ = Handle<Context>();
+ return;
+ }
+
+ // For a FUNCTION_SCOPE we locate the paused function's scope in the
+ // serialized tree. For top-level scopes (EVAL_SCOPE, SCRIPT_SCOPE,
+ // MODULE_SCOPE) the closure scope is the root scope (index 0).
+ std::optional<DebugScriptScope> debug_closure_scope =
+ scope_info->scope_type() == FUNCTION_SCOPE
+ ? FindClosureScope(debug_scope_info_, shared_info->StartPosition(),
+ shared_info->EndPosition(),
+ scope_info->scope_type())
+ : DebugScriptScope::FromIndex(debug_scope_info_, 0);
+ if (!debug_closure_scope.has_value()) {
+ context_ = Handle<Context>();
+ return;
+ }
+ closure_scope_index_ = debug_closure_scope->scope_index();
+ start_scope_index_ =
+ FindInnermostScope(*debug_closure_scope, GetSourcePosition())
+ .scope_index();
+ current_scope_index_ = start_scope_index_;
+
+ if (ignore_nested_scopes) {
+ current_scope_index_ = closure_scope_index_;
+ start_scope_index_ = current_scope_index_;
+ // ignore_nested_scopes is only used for the return-position breakpoint,
+ // so we can safely assume that the closure context for the current
+ // function exists if it needs one.
+ if (closure_scope().needs_context()) {
+ context_ = handle(context_->closure_context(), isolate_);
+ }
}
+
+ UnwrapEvaluationContext();
}
void ScopeIterator::UnwrapEvaluationContext() {
@@ -401,17 +197,17 @@ DirectHandle<JSObject> ScopeIterator::MaterializeScopeDetails() {
}
bool ScopeIterator::HasPositionInfo() {
- return InInnerScope() || !IsNativeContext(*context_);
+ return HasScope() || !IsNativeContext(*context_);
}
int ScopeIterator::start_position() {
- if (InInnerScope()) return current_scope_->start_position();
+ if (HasScope()) return current_scope().start_position();
if (IsNativeContext(*context_)) return 0;
return context_->closure_context()->scope_info()->StartPosition();
}
int ScopeIterator::end_position() {
- if (InInnerScope()) return current_scope_->end_position();
+ if (HasScope()) return current_scope().end_position();
if (IsNativeContext(*context_)) return 0;
return context_->closure_context()->scope_info()->EndPosition();
}
@@ -456,17 +252,17 @@ bool ScopeIterator::HasContext() const {
//
// We can detect this by comparing the scope ID of the parsed scope and the
// runtime scope.
- if (current_scope_ && NeedsContext() &&
- current_scope_->UniqueIdInScript() !=
+ if (HasScope() && NeedsContext() &&
+ current_scope().unique_id_in_script() !=
context_->scope_info()->UniqueIdInScript()) {
return false;
}
- return !InInnerScope() || NeedsContext();
+ return !HasScope() || NeedsContext();
}
bool ScopeIterator::NeedsContext() const {
- const bool needs_context = current_scope_->NeedsContext();
+ const bool needs_context = current_scope().needs_context();
// We try very hard to ensure that a function's context is already
// available when we pause right at the beginning of that function.
@@ -477,9 +273,9 @@ bool ScopeIterator::NeedsContext() const {
// We check this by ensuring that the current context is not the closure
// context should the function need one. In that case the function has already
// pushed the context and we are good.
- CHECK_IMPLIES(needs_context && current_scope_ == closure_scope_ &&
- (current_scope_->is_function_scope() ||
- current_scope_->is_eval_scope()) &&
+ CHECK_IMPLIES(needs_context && current_scope_index_ == closure_scope_index_ &&
+ (current_scope().is_function_scope() ||
+ current_scope().is_eval_scope()) &&
!function_.is_null(),
function_->context() != *context_);
@@ -487,10 +283,10 @@ bool ScopeIterator::NeedsContext() const {
}
bool ScopeIterator::AdvanceOneScope() {
- if (!current_scope_ || !current_scope_->outer_scope()) return false;
-
- current_scope_ = current_scope_->outer_scope();
- CollectLocalsFromCurrentScope();
+ if (!HasScope()) return false;
+ std::optional<DebugScriptScope> parent = current_scope().parent();
+ if (!parent.has_value()) return false;
+ current_scope_index_ = parent->scope_index();
return true;
}
@@ -498,36 +294,23 @@ void ScopeIterator::AdvanceOneContext() {
DCHECK(!IsNativeContext(*context_));
DCHECK(!context_->previous().is_null());
context_ = handle(context_->previous(), isolate_);
-
- // The locals blocklist is always associated with a context. So when we
- // move one context up, we also reset the locals_ blocklist.
- locals_ = StringSet::New(isolate_);
}
void ScopeIterator::AdvanceScope() {
- DCHECK(InInnerScope());
+ DCHECK(HasScope());
do {
if (NeedsAndHasContext()) {
- // current_scope_ needs a context so moving one scope up requires us to
+ // current_scope() needs a context so moving one scope up requires us to
// also move up one context.
AdvanceOneContext();
}
CHECK(AdvanceOneScope());
- } while (current_scope_->is_hidden());
+ } while (current_scope().is_hidden());
}
-void ScopeIterator::AdvanceContext() {
- AdvanceOneContext();
-
- // While advancing one context, we need to advance at least one
- // scope, but until we hit the next scope that actually requires
- // a context. All the locals collected along the way build the
- // blocklist for debug-evaluate for this context.
- while (AdvanceOneScope() && !NeedsContext()) {
- }
-}
+void ScopeIterator::AdvanceContext() { AdvanceOneContext(); }
void ScopeIterator::Next() {
DCHECK(!Done());
@@ -542,37 +325,41 @@ void ScopeIterator::Next() {
return;
}
- bool leaving_closure = current_scope_ == closure_scope_;
+ bool leaving_closure = current_scope_index_ == closure_scope_index_;
if (scope_type == ScopeTypeScript) {
DCHECK_IMPLIES(InInnerScope() && !leaving_closure,
- current_scope_->is_script_scope());
+ current_scope().is_script_scope());
seen_script_scope_ = true;
if (context_->IsScriptContext()) {
context_ = handle(context_->previous(), isolate_);
}
+ if (leaving_closure) {
+ current_scope_index_ = -1;
+ }
} else if (!InInnerScope()) {
AdvanceContext();
} else {
- DCHECK_NOT_NULL(current_scope_);
- AdvanceScope();
-
+ DCHECK_NE(current_scope_index_, -1);
if (leaving_closure) {
- DCHECK(current_scope_ != closure_scope_);
- // If the current_scope_ doesn't need a context, we advance the scopes
- // and collect the blocklist along the way until we find the scope
- // that should match `context_`.
- // But only do this if we have complete scope information.
- while (!NeedsContext() && AdvanceOneScope()) {
+ // DebugScriptScope represents the entire script's scope tree, so calling
+ // AdvanceScope() here would step into the enclosing outer scope. Outside
+ // the paused closure, ScopeIterator iterates purely via runtime context_
+ // (!InInnerScope()). Consume the closure's context if it had one and
+ // reset the scope cursor.
+ if (NeedsAndHasContext()) {
+ AdvanceOneContext();
}
+ current_scope_index_ = -1;
+ } else {
+ AdvanceScope();
}
}
- MaybeCollectAndStoreLocalBlocklists();
UnwrapEvaluationContext();
- DCHECK_IMPLIES(current_scope_ && NeedsAndHasContext(),
- current_scope_->UniqueIdInScript() ==
+ DCHECK_IMPLIES(HasScope() && NeedsAndHasContext(),
+ current_scope().unique_id_in_script() ==
context_->scope_info()->UniqueIdInScript());
if (leaving_closure) function_ = Handle<JSFunction>();
@@ -581,13 +368,13 @@ void ScopeIterator::Next() {
// Return the type of the current scope.
ScopeIterator::ScopeType ScopeIterator::Type() const {
DCHECK(!Done());
- if (InInnerScope()) {
- switch (current_scope_->scope_type()) {
+ if (HasScope()) {
+ switch (current_scope().scope_type()) {
case FUNCTION_SCOPE:
DCHECK_IMPLIES(NeedsAndHasContext(),
context_->IsFunctionContext() ||
context_->IsDebugEvaluateContext());
- return ScopeTypeLocal;
+ return InInnerScope() ? ScopeTypeLocal : ScopeTypeClosure;
case MODULE_SCOPE:
DCHECK_IMPLIES(NeedsAndHasContext(), context_->IsModuleContext());
return ScopeTypeModule;
@@ -600,7 +387,7 @@ ScopeIterator::ScopeType ScopeIterator::Type() const {
DCHECK_IMPLIES(NeedsAndHasContext(), context_->IsWithContext());
return ScopeTypeWith;
case CATCH_SCOPE:
- DCHECK(context_->IsCatchContext());
+ DCHECK_IMPLIES(NeedsAndHasContext(), context_->IsCatchContext());
return ScopeTypeCatch;
case BLOCK_SCOPE:
case CLASS_SCOPE:
@@ -608,7 +395,7 @@ ScopeIterator::ScopeType ScopeIterator::Type() const {
return ScopeTypeBlock;
case EVAL_SCOPE:
DCHECK_IMPLIES(NeedsAndHasContext(), context_->IsEvalContext());
- return ScopeTypeEval;
+ return InInnerScope() ? ScopeTypeEval : ScopeTypeClosure;
case SHADOW_REALM_SCOPE:
DCHECK_IMPLIES(NeedsAndHasContext(), IsNativeContext(*context_));
// TODO(v8:11989): New ScopeType for ShadowRealms?
@@ -658,11 +445,14 @@ Handle<JSObject> ScopeIterator::ScopeObject(Mode mode) {
Handle<JSObject> scope = isolate_->factory()->NewSlowJSObjectWithNullProto();
auto visitor = [=, this](DirectHandle<String> name,
DirectHandle<Object> value, ScopeType scope_type) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*value));
+#endif
if (IsOptimizedOut(*value)) {
JSObject::SetAccessor(
scope, name, isolate_->factory()->value_unavailable_accessor(), NONE)
.Check();
- } else if (IsTheHole(*value)) {
+ } else if (IsTdzHole(*value)) {
const bool is_overriden_repl_let =
scope_type == ScopeTypeScript &&
JSReceiver::HasOwnProperty(isolate_, scope, name).FromMaybe(true);
@@ -698,7 +488,7 @@ void ScopeIterator::VisitScope(const Visitor& visitor, Mode mode) const {
case ScopeTypeEval:
return VisitLocalScope(visitor, mode, Type());
case ScopeTypeModule:
- if (InInnerScope()) {
+ if (HasScope()) {
return VisitLocalScope(visitor, mode, Type());
}
DCHECK_EQ(Mode::ALL, mode);
@@ -728,7 +518,7 @@ bool ScopeIterator::SetVariableValue(Handle<String> name,
case ScopeTypeBlock:
case ScopeTypeCatch:
case ScopeTypeModule:
- if (InInnerScope()) return SetLocalVariableValue(name, value);
+ if (HasScope()) return SetLocalVariableValue(name, value);
if (Type() == ScopeTypeModule && SetModuleVariableValue(name, value)) {
return true;
}
@@ -736,11 +526,9 @@ bool ScopeIterator::SetVariableValue(Handle<String> name,
case ScopeTypeLocal:
case ScopeTypeClosure:
- if (InInnerScope()) {
- DCHECK_EQ(ScopeTypeLocal, Type());
+ if (HasScope()) {
if (SetLocalVariableValue(name, value)) return true;
- // There may not be an associated context since we're InInnerScope().
- if (!NeedsContext()) return false;
+ if (!HasContext()) return false;
} else {
DCHECK_EQ(ScopeTypeClosure, Type());
if (SetContextVariableValue(name, value)) return true;
@@ -757,20 +545,10 @@ bool ScopeIterator::SetVariableValue(Handle<String> name,
}
bool ScopeIterator::ClosureScopeHasThisReference() const {
- // closure_scope_ can be nullptr if parsing failed. See the TODO in
- // TryParseAndRetrieveScopes.
- return closure_scope_ && !closure_scope_->has_this_declaration() &&
- closure_scope_->HasThisReference();
-}
-
-void ScopeIterator::CollectLocalsFromCurrentScope() {
- DCHECK(IsStringSet(*locals_));
- for (Variable* var : *current_scope_->locals()) {
- if (var->location() == VariableLocation::PARAMETER ||
- var->location() == VariableLocation::LOCAL) {
- locals_ = StringSet::Add(isolate_, locals_, var->name());
- }
- }
+ // closure_scope_index_ can be -1 if parsing failed.
+ return closure_scope_index_ != -1 &&
+ !closure_scope().has_this_declaration() &&
+ closure_scope().has_this_reference();
}
#ifdef DEBUG
@@ -804,17 +582,21 @@ void ScopeIterator::DebugPrint() {
case ScopeIterator::ScopeTypeCatch:
os << "Catch:\n";
- Print(context_->extension(), os);
- Print(context_->GetNoCell(Context::THROWN_OBJECT_INDEX), os);
+ if (HasContext()) {
+ Print(context_->extension(), os);
+ Print(context_->GetNoCell(Context::THROWN_OBJECT_INDEX), os);
+ }
break;
case ScopeIterator::ScopeTypeClosure:
os << "Closure:\n";
- Print(*context_, os);
- if (context_->has_extension()) {
- DirectHandle<HeapObject> extension(context_->extension(), isolate_);
- DCHECK(IsJSContextExtensionObject(*extension));
- Print(*extension, os);
+ if (HasContext()) {
+ Print(*context_, os);
+ if (context_->has_extension()) {
+ DirectHandle<HeapObject> extension(context_->extension(), isolate_);
+ DCHECK(IsJSContextExtensionObject(*extension));
+ Print(*extension, os);
+ }
}
break;
@@ -902,15 +684,15 @@ bool ScopeIterator::VisitContextLocals(const Visitor& visitor,
bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
ScopeType scope_type) const {
- if (mode == Mode::STACK && current_scope_->is_declaration_scope() &&
- current_scope_->AsDeclarationScope()->has_this_declaration()) {
+ if (mode == Mode::STACK && current_scope().has_this_declaration()) {
+ DCHECK(InInnerScope());
// TODO(bmeurer): We should refactor the general variable lookup
// around "this", since the current way is rather hacky when the
// receiver is context-allocated.
- auto this_var = current_scope_->AsDeclarationScope()->receiver();
+ auto [this_alloc, this_index] = current_scope().receiver_info();
Handle<Object> receiver =
- this_var->location() == VariableLocation::CONTEXT
- ? handle(context_->GetNoCell(this_var->index()), isolate_)
+ this_alloc == VariableAllocationInfo::CONTEXT
+ ? handle(context_->GetNoCell(this_index), isolate_)
: frame_inspector_ == nullptr ? handle(generator_->receiver(), isolate_)
: frame_inspector_->GetReceiver();
if (visitor(isolate_->factory()->this_string(), receiver, scope_type)) {
@@ -918,30 +700,41 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
}
}
- if (current_scope_->is_function_scope()) {
- Variable* function_var =
- current_scope_->AsDeclarationScope()->function_var();
- if (function_var != nullptr) {
- Handle<JSFunction> function = frame_inspector_ == nullptr
- ? function_
- : frame_inspector_->GetFunction();
- Handle<String> name = function_var->name();
- if (visitor(name, function, scope_type)) return true;
+ if (current_scope().has_function_variable()) {
+ DirectHandle<String> name(current_scope().function_variable_name(),
+ isolate_);
+ Handle<Object> function_value;
+ if (InInnerScope()) {
+ function_value = frame_inspector_ == nullptr
+ ? function_
+ : frame_inspector_->GetFunction();
+ } else {
+ auto [fn_alloc, fn_index] = current_scope().function_variable_info();
+ if (fn_alloc == VariableAllocationInfo::CONTEXT && HasContext()) {
+ function_value = indirect_handle(
+ Context::Get(context_, fn_index, isolate_), isolate_);
+ } else {
+ function_value = isolate_->factory()->the_hole_value();
+ }
}
+ if (visitor(name, function_value, scope_type)) return true;
}
- for (Variable* var : *current_scope_->locals()) {
- if (ScopeInfo::VariableIsSynthetic(*var->name())) {
+ DebugScriptScope scope = current_scope();
+ auto [args_alloc, args_index] = scope.arguments_info();
+ for (int i = 0; i < scope.variable_count(); ++i) {
+ DebugVariableInfo var = scope.variable(i);
+ if (var.is_synthetic) {
// We want to materialize "new.target" for debug-evaluate.
if (mode != Mode::STACK ||
- !var->name()->Equals(*isolate_->factory()->dot_new_target_string())) {
+ !var.name->Equals(*isolate_->factory()->dot_new_target_string())) {
continue;
}
}
- int index = var->index();
+ int index = var.index;
Handle<Object> value;
- switch (var->location()) {
+ switch (var.location) {
case VariableLocation::LOOKUP:
UNREACHABLE();
@@ -951,7 +744,9 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
continue;
case VariableLocation::PARAMETER: {
- if (frame_inspector_ == nullptr) {
+ if (!InInnerScope()) {
+ value = isolate_->factory()->the_hole_value();
+ } else if (frame_inspector_ == nullptr) {
// Get the variable from the suspended generator.
DCHECK(!generator_.is_null());
Tagged<FixedArray> parameters_and_registers =
@@ -960,7 +755,7 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
CHECK_LT(static_cast<uint32_t>(index),
parameters_and_registers->ulength().value());
value = handle(parameters_and_registers->get(index), isolate_);
- } else if (var->IsReceiver()) {
+ } else if (var.is_receiver) {
value = frame_inspector_->GetReceiver();
} else {
JavaScriptFrame* frame = GetFrame();
@@ -976,7 +771,9 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
}
case VariableLocation::LOCAL:
- if (frame_inspector_ == nullptr) {
+ if (!InInnerScope()) {
+ value = isolate_->factory()->the_hole_value();
+ } else if (frame_inspector_ == nullptr) {
// Get the variable from the suspended generator.
DCHECK(!generator_.is_null());
Tagged<FixedArray> parameters_and_registers =
@@ -997,19 +794,18 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
value = frame_inspector_->GetExpression(index);
if (IsOptimizedOut(*value)) {
// We'll rematerialize this later.
- if (current_scope_->is_declaration_scope() &&
- current_scope_->AsDeclarationScope()->arguments() == var) {
+ if (args_alloc == VariableAllocationInfo::STACK &&
+ args_index == var.index) {
continue;
}
- } else if (IsLexicalVariableMode(var->mode()) &&
- IsUndefined(*value) &&
+ } else if (IsLexicalVariableMode(var.mode) && IsUndefined(*value) &&
GetSourcePosition() != kNoSourcePosition &&
- GetSourcePosition() <= var->initializer_position()) {
+ GetSourcePosition() <= var.initializer_position) {
// Variables that are `undefined` could also mean an elided hole
// write. We explicitly check the static scope information if we
// are currently stopped before the variable is actually initialized
// which means we are in the middle of that var's TDZ.
- value = isolate_->factory()->the_hole_value();
+ value = isolate_->factory()->tdz_hole_value();
}
}
break;
@@ -1019,12 +815,10 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
if (!HasContext()) {
// If the context was not yet pushed we report the variable as
// unavailable.
- value = isolate_->factory()->the_hole_value();
+ value = isolate_->factory()->tdz_hole_value();
break;
}
- DCHECK(var->IsContextSlot());
- DCHECK_EQ(context_->scope_info()->ContextSlotIndex(*var->name()),
- index);
+ DCHECK_EQ(context_->scope_info()->ContextSlotIndex(var.name), index);
value =
indirect_handle(Context::Get(context_, index, isolate_), isolate_);
break;
@@ -1033,12 +827,14 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
if (mode == Mode::STACK) continue;
// if (var->IsExport()) continue;
DirectHandle<SourceTextModule> module(context_->module(), isolate_);
- value = SourceTextModule::LoadVariable(isolate_, module, var->index());
+ value = SourceTextModule::LoadVariable(isolate_, module, var.index);
break;
}
}
- if (visitor(var->name(), value, scope_type)) return true;
+ if (visitor(direct_handle(var.name, isolate_), value, scope_type)) {
+ return true;
+ }
}
return false;
}
@@ -1059,14 +855,14 @@ Handle<JSObject> ScopeIterator::WithContextExtension() {
// block context.
void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode,
ScopeType scope_type) const {
- if (InInnerScope()) {
+ if (HasScope()) {
if (VisitLocals(visitor, mode, scope_type)) return;
if (mode == Mode::STACK && Type() == ScopeTypeLocal) {
// Hide |this| in arrow functions that may be embedded in other functions
// but don't force |this| to be context-allocated. Otherwise we'd find the
// wrong |this| value.
- if (!closure_scope_->has_this_declaration() &&
- !closure_scope_->HasThisReference()) {
+ if (!closure_scope().has_this_declaration() &&
+ !closure_scope().has_this_reference()) {
if (visitor(isolate_->factory()->this_string(),
isolate_->factory()->undefined_value(), scope_type)) {
return;
@@ -1077,19 +873,19 @@ void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode,
// suspended generators. We'd need to read the arguments out from the
// suspended generator rather than from an activation as
// FunctionGetArguments does.
- if (frame_inspector_ != nullptr && !closure_scope_->is_arrow_scope()) {
- Variable* arguments_var = closure_scope_->arguments();
- bool arguments_optimized_out = arguments_var == nullptr;
+ if (frame_inspector_ != nullptr && !closure_scope().is_arrow_scope()) {
+ auto [args_alloc, args_index] = closure_scope().arguments_info();
+ bool arguments_optimized_out =
+ args_alloc == VariableAllocationInfo::NONE;
JavaScriptFrame* frame = GetFrame();
if (!arguments_optimized_out &&
- arguments_var->location() == VariableLocation::LOCAL) {
- int index = arguments_var->index();
+ args_alloc == VariableAllocationInfo::STACK) {
if (frame->is_unoptimized()) {
- CHECK_GE(index, 0);
- CHECK_LT(index, frame->ComputeExpressionsCount());
+ CHECK_GE(args_index, 0);
+ CHECK_LT(args_index, frame->ComputeExpressionsCount());
}
arguments_optimized_out =
- IsOptimizedOut(*frame_inspector_->GetExpression(index));
+ IsOptimizedOut(*frame_inspector_->GetExpression(args_index));
}
if (arguments_optimized_out) {
@@ -1136,16 +932,18 @@ void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode,
bool ScopeIterator::SetLocalVariableValue(DirectHandle<String> variable_name,
DirectHandle<Object> new_value) {
- // TODO(verwaest): Walk parameters backwards, not forwards.
- // TODO(verwaest): Use VariableMap rather than locals() list for lookup.
- for (Variable* var : *current_scope_->locals()) {
- if (String::Equals(isolate_, var->name(), variable_name)) {
- int index = var->index();
- switch (var->location()) {
+ Tagged<InternalizedString> internalized_name =
+ CheckedCast<InternalizedString>(*variable_name);
+ DebugScriptScope scope = current_scope();
+ for (int i = 0; i < scope.variable_count(); ++i) {
+ DebugVariableInfo var = scope.variable(i);
+ if (var.name == internalized_name) {
+ int index = var.index;
+ switch (var.location) {
case VariableLocation::LOOKUP:
case VariableLocation::UNALLOCATED:
// Drop assignments to unallocated locals.
- DCHECK(var->is_this() ||
+ DCHECK(*variable_name == ReadOnlyRoots(isolate_).this_string() ||
*variable_name == ReadOnlyRoots(isolate_).arguments_string());
return false;
@@ -1154,7 +952,7 @@ bool ScopeIterator::SetLocalVariableValue(DirectHandle<String> variable_name,
return false;
case VariableLocation::PARAMETER: {
- if (var->is_this()) return false;
+ if (!InInnerScope() || var.is_receiver) return false;
if (frame_inspector_ == nullptr) {
// Set the variable in the suspended generator.
DCHECK(!generator_.is_null());
@@ -1174,6 +972,7 @@ bool ScopeIterator::SetLocalVariableValue(DirectHandle<String> variable_name,
}
case VariableLocation::LOCAL:
+ if (!InInnerScope()) return false;
if (frame_inspector_ == nullptr) {
// Set the variable in the suspended generator.
DCHECK(!generator_.is_null());
@@ -1198,8 +997,7 @@ bool ScopeIterator::SetLocalVariableValue(DirectHandle<String> variable_name,
return true;
case VariableLocation::CONTEXT:
- DCHECK(var->IsContextSlot());
-
+ if (!HasContext()) return false;
// We know of at least one open bug where the context and scope chain
// don't match (https://crbug.com/753338).
// Skip the write if the context's ScopeInfo doesn't know anything
@@ -1212,9 +1010,9 @@ bool ScopeIterator::SetLocalVariableValue(DirectHandle<String> variable_name,
return true;
case VariableLocation::MODULE:
- if (!var->IsExport()) return false;
+ if (!HasContext() || !var.is_export()) return false;
DirectHandle<SourceTextModule> module(context_->module(), isolate_);
- SourceTextModule::StoreVariable(module, var->index(), new_value);
+ SourceTextModule::StoreVariable(module, var.index, new_value);
return true;
}
UNREACHABLE();
@@ -1283,189 +1081,5 @@ bool ScopeIterator::SetScriptVariableValue(DirectHandle<String> variable_name,
return false;
}
-namespace {
-
-// Given the scope and context of a paused function, this class calculates
-// all the necessary block lists on the scope chain and stores them in the
-// global LocalsBlockListCache ephemeron table.
-//
-// Doc: bit.ly/chrome-devtools-debug-evaluate-design.
-//
-// The algorithm works in a single walk of the scope chain from the
-// paused function scope outwards to the script scope.
-//
-// When we step from scope "a" to its outer scope "b", we do:
-//
-// 1. Add all stack-allocated variables from "b" to the blocklists.
-// 2. Does "b" need a context? If yes:
-// - Store all current blocklists in the global table
-// - Start a new blocklist for scope "b"
-// 3. Is "b" a function scope without a context? If yes:
-// - Start a new blocklist for scope "b"
-//
-class LocalBlocklistsCollector {
- public:
- LocalBlocklistsCollector(Isolate* isolate, Handle<Script> script,
- Handle<Context> context,
- DeclarationScope* closure_scope);
- void CollectAndStore();
-
- private:
- void InitializeWithClosureScope();
- void AdvanceToNextNonHiddenScope();
- void CollectCurrentLocalsIntoBlocklists();
- DirectHandle<ScopeInfo> FindScopeInfoForScope(Scope* scope) const;
- void StoreFunctionBlocklists(DirectHandle<ScopeInfo> outer_scope_info);
-
- Isolate* isolate_;
- Handle<Script> script_;
- Handle<Context> context_;
- Scope* scope_;
- DeclarationScope* closure_scope_;
-
- Handle<StringSet> context_blocklist_;
- std::map<Scope*, IndirectHandle<StringSet>> function_blocklists_;
- bool has_matched_first_context_ = false;
-};
-
-LocalBlocklistsCollector::LocalBlocklistsCollector(
- Isolate* isolate, Handle<Script> script, Handle<Context> context,
- DeclarationScope* closure_scope)
- : isolate_(isolate),
- script_(script),
- context_(context),
- scope_(closure_scope),
- closure_scope_(closure_scope) {}
-
-void LocalBlocklistsCollector::InitializeWithClosureScope() {
- CHECK(scope_->is_declaration_scope());
- function_blocklists_.emplace(scope_, StringSet::New(isolate_));
- context_blocklist_ = StringSet::New(isolate_);
- has_matched_first_context_ = scope_->NeedsContext();
-}
-
-void LocalBlocklistsCollector::AdvanceToNextNonHiddenScope() {
- DCHECK(scope_ && scope_->outer_scope());
- do {
- scope_ = scope_->outer_scope();
- CHECK(scope_);
- } while (scope_->is_hidden());
-}
-
-void LocalBlocklistsCollector::CollectCurrentLocalsIntoBlocklists() {
- for (Variable* var : *scope_->locals()) {
- if (var->location() == VariableLocation::PARAMETER ||
- var->location() == VariableLocation::LOCAL) {
- if (!context_blocklist_.is_null()) {
- context_blocklist_ =
- StringSet::Add(isolate_, context_blocklist_, var->name());
- }
- for (auto& pair : function_blocklists_) {
- pair.second = StringSet::Add(isolate_, pair.second, var->name());
- }
- }
- }
-}
-
-DirectHandle<ScopeInfo> LocalBlocklistsCollector::FindScopeInfoForScope(
- Scope* scope) const {
- DisallowGarbageCollection no_gc;
- SharedFunctionInfo::ScriptIterator iterator(isolate_, *script_);
- for (Tagged<SharedFunctionInfo> info = iterator.Next(); !info.is_null();
- info = iterator.Next()) {
- Tagged<ScopeInfo> scope_info = info->scope_info();
- if (info->is_compiled() && !scope_info.is_null() &&
- scope->start_position() == info->StartPosition() &&
- scope->end_position() == info->EndPosition() &&
- scope->scope_type() == scope_info->scope_type()) {
- return direct_handle(scope_info, isolate_);
- }
- }
- return DirectHandle<ScopeInfo>();
-}
-
-void LocalBlocklistsCollector::StoreFunctionBlocklists(
- DirectHandle<ScopeInfo> outer_scope_info) {
- for (const auto& pair : function_blocklists_) {
- DirectHandle<ScopeInfo> scope_info = FindScopeInfoForScope(pair.first);
- // If we don't find a ScopeInfo it's not tragic. It means we'll do
- // a full-reparse in case we pause in that function in the future.
- // The only ScopeInfo that MUST be found is for the closure_scope_.
- CHECK_IMPLIES(pair.first == closure_scope_, !scope_info.is_null());
- if (scope_info.is_null()) continue;
- isolate_->LocalsBlockListCacheSet(scope_info, outer_scope_info,
- pair.second);
- }
-}
-
-void LocalBlocklistsCollector::CollectAndStore() {
- InitializeWithClosureScope();
-
- while (scope_->outer_scope() && !IsNativeContext(*context_)) {
- AdvanceToNextNonHiddenScope();
-
- if (!has_matched_first_context_ && scope_->NeedsContext()) {
- context_blocklist_ = StringSet::New(isolate_);
- }
-
- // 1. Add all stack-allocated variables of `scope_` to the various lists.
- CollectCurrentLocalsIntoBlocklists();
-
- // 2. If the current scope requires a context then all the blocklists "stop"
- // here and we store them. Next, advance the current context so
- // `context_` and `scope_` match again.
- if (scope_->NeedsContext()) {
- if (has_matched_first_context_) {
- // Only store the block list and advance the context if we have already
- // matched our first context. This handles the case when we start on
- // a closure scope that doesn't require a context. In that case
- // `context_` is already the right context for `scope_` so we don't
- // need to advance `context_`.
- isolate_->LocalsBlockListCacheSet(
- direct_handle(context_->scope_info(), isolate_),
- direct_handle(context_->previous()->scope_info(), isolate_),
- context_blocklist_);
- context_ = handle(context_->previous(), isolate_);
- context_blocklist_ = StringSet::New(isolate_);
- }
- has_matched_first_context_ = true;
-
- StoreFunctionBlocklists(direct_handle(context_->scope_info(), isolate_));
- function_blocklists_.clear();
- } else if (scope_->is_function_scope()) {
- // 3. If `scope` is a function scope with an SFI, start recording
- // locals for its ScopeInfo.
- CHECK(!scope_->NeedsContext());
- function_blocklists_.emplace(scope_, StringSet::New(isolate_));
- }
- }
-
- if (has_matched_first_context_ && !IsNativeContext(*context_)) {
- isolate_->LocalsBlockListCacheSet(
- direct_handle(context_->scope_info(), isolate_),
- direct_handle(context_->previous()->scope_info(), isolate_),
- context_blocklist_);
- }
-
- // In case we don't have any outer scopes we still need to record the empty
- // block list for the paused function to prevent future re-parses.
- StoreFunctionBlocklists(direct_handle(context_->scope_info(), isolate_));
-}
-
-} // namespace
-
-void ScopeIterator::MaybeCollectAndStoreLocalBlocklists() const {
- if (!calculate_blocklists_ || current_scope_ != closure_scope_ ||
- Type() == ScopeTypeScript) {
- return;
- }
-
- DCHECK(IsTheHole(isolate_->LocalsBlockListCacheGet(
- direct_handle(function_->shared()->scope_info(), isolate_))));
- LocalBlocklistsCollector collector(isolate_, script_, context_,
- closure_scope_);
- collector.CollectAndStore();
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/debug/debug-scopes.h b/deps/v8/src/debug/debug-scopes.h
index ca7a8717f4f..a03b3ae4235 100644
--- a/deps/v8/src/debug/debug-scopes.h
+++ b/deps/v8/src/debug/debug-scopes.h
@@ -6,13 +6,12 @@
#define V8_DEBUG_DEBUG_SCOPES_H_
#include "src/debug/debug-frames.h"
-#include "src/parsing/parse-info.h"
+#include "src/debug/debug-scope-info.h"
namespace v8 {
namespace internal {
class JavaScriptFrame;
-class ParseInfo;
// Iterate over the actual scopes visible from a stack frame or from a closure.
// The iteration proceeds from the innermost visible nested scope outwards.
@@ -40,16 +39,7 @@ class V8_EXPORT_PRIVATE ScopeIterator {
static const int kScopeDetailsFunctionIndex = 5;
static const int kScopeDetailsSize = 6;
- enum class ReparseStrategy {
- kFunctionLiteral,
- // Checks whether the paused function (and its scope chain) already has
- // its blocklist calculated and re-parses the whole script if not.
- // Otherwise only the function literal is re-parsed.
- kScriptIfNeeded,
- };
-
- ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
- ReparseStrategy strategy);
+ ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector);
ScopeIterator(Isolate* isolate, DirectHandle<JSFunction> function);
ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
@@ -93,9 +83,6 @@ class V8_EXPORT_PRIVATE ScopeIterator {
bool ClosureScopeHasThisReference() const;
- // Populate the set with collected non-local variable names.
- DirectHandle<StringSet> GetLocals() { return locals_; }
-
// Similar to JSFunction::GetName return the function's name or it's inferred
// name.
DirectHandle<Object> GetFunctionDebugName() const;
@@ -111,7 +98,13 @@ class V8_EXPORT_PRIVATE ScopeIterator {
void DebugPrint();
#endif
- bool InInnerScope() const { return !function_.is_null(); }
+ // Whether the current scope is backed by a scope in `debug_scope_info_`.
+ bool HasScope() const { return current_scope_index_ != -1; }
+ // Whether the current scope is backed by `debug_scope_info_` and belongs to
+ // the paused function (i.e. its stack-allocated variables are available).
+ bool InInnerScope() const {
+ return !function_.is_null() && HasScope();
+ }
bool HasContext() const;
bool NeedsContext() const;
bool NeedsAndHasContext() const { return NeedsContext() && HasContext(); }
@@ -119,11 +112,13 @@ class V8_EXPORT_PRIVATE ScopeIterator {
DCHECK(HasContext());
return context_;
}
+ std::optional<DebugScriptScope> CurrentDebugScope() const {
+ if (current_scope_index_ == -1) return std::nullopt;
+ return current_scope();
+ }
private:
Isolate* isolate_;
- std::unique_ptr<ReusableUnoptimizedCompileState> reusable_compile_state_;
- std::unique_ptr<ParseInfo> info_;
FrameInspector* const frame_inspector_ = nullptr;
Handle<JSGeneratorObject> generator_;
@@ -133,12 +128,21 @@ class V8_EXPORT_PRIVATE ScopeIterator {
Handle<Context> context_;
Handle<Script> script_;
- Handle<StringSet> locals_;
- DeclarationScope* closure_scope_ = nullptr;
- Scope* start_scope_ = nullptr;
- Scope* current_scope_ = nullptr;
+ // Serialized scope tree of the paused script and indices into it.
+ // `current_scope_index_` is set to -1 once iteration leaves
+ // `closure_scope_index_` (matching `function_` becoming null).
+ Handle<DebugScriptScopeInfo> debug_scope_info_;
+ int start_scope_index_ = -1;
+ int closure_scope_index_ = -1;
+ int current_scope_index_ = -1;
bool seen_script_scope_ = false;
- bool calculate_blocklists_ = false;
+
+ DebugScriptScope current_scope() const {
+ return DebugScriptScope::FromIndex(debug_scope_info_, current_scope_index_);
+ }
+ DebugScriptScope closure_scope() const {
+ return DebugScriptScope::FromIndex(debug_scope_info_, closure_scope_index_);
+ }
inline JavaScriptFrame* GetFrame() const {
return frame_inspector_->javascript_frame();
@@ -148,24 +152,16 @@ class V8_EXPORT_PRIVATE ScopeIterator {
void AdvanceOneContext();
void AdvanceScope();
void AdvanceContext();
- void CollectLocalsFromCurrentScope();
-
- // Calculates all the block list starting at the current scope and stores
- // them in the global "LocalsBlocklistCache".
- //
- // Is a no-op unless `calculate_blocklists_` is true and
- // current_scope_ == closure_scope_. Otherwise `context_` does not match
- // with current_scope_/closure_scope_.
- void MaybeCollectAndStoreLocalBlocklists() const;
int GetSourcePosition() const;
- void TryParseAndRetrieveScopes(ReparseStrategy strategy);
+ void TryParseAndRetrieveScopes();
void UnwrapEvaluationContext();
- using Visitor = std::function<bool(Handle<String> name, Handle<Object> value,
- ScopeType scope_type)>;
+ using Visitor =
+ std::function<bool(DirectHandle<String> name, DirectHandle<Object> value,
+ ScopeType scope_type)>;
Handle<JSObject> WithContextExtension();
diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.cc b/deps/v8/src/debug/debug-stack-trace-iterator.cc
index 6bc3e90deef..dc3ddac1860 100644
--- a/deps/v8/src/debug/debug-stack-trace-iterator.cc
+++ b/deps/v8/src/debug/debug-stack-trace-iterator.cc
@@ -93,9 +93,7 @@ v8::MaybeLocal<v8::Value> DebugStackTraceIterator::GetReceiver() const {
// Arrow function defined in top level function without references to
// variables may have NativeContext as context.
if (!context->IsFunctionContext()) return v8::MaybeLocal<v8::Value>();
- ScopeIterator scope_iterator(
- isolate_, frame_inspector_.get(),
- ScopeIterator::ReparseStrategy::kFunctionLiteral);
+ ScopeIterator scope_iterator(isolate_, frame_inspector_.get());
// We lookup this variable in function context only when it is used in arrow
// function otherwise V8 can optimize it out.
if (!scope_iterator.ClosureScopeHasThisReference()) {
@@ -106,12 +104,15 @@ v8::MaybeLocal<v8::Value> DebugStackTraceIterator::GetReceiver() const {
*isolate_->factory()->this_string());
if (slot_index < 0) return v8::MaybeLocal<v8::Value>();
DirectHandle<Object> value(context->GetNoCell(slot_index), isolate_);
- if (IsTheHole(*value)) return v8::MaybeLocal<v8::Value>();
+ if (IsTdzHole(*value)) return v8::MaybeLocal<v8::Value>();
return Utils::ToLocal(value);
}
DirectHandle<Object> value = frame_inspector_->GetReceiver();
- if (value.is_null() || (IsSmi(*value) || !IsTheHole(*value))) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(value.is_null() || !IsTheHole(*value));
+#endif
+ if (value.is_null() || (IsSmi(*value) || !IsTdzHole(*value))) {
return Utils::ToLocal(value);
}
return v8::MaybeLocal<v8::Value>();
diff --git a/deps/v8/src/debug/debug-wasm-objects.cc b/deps/v8/src/debug/debug-wasm-objects.cc
index 9ab74cd1176..0cf893b6c41 100644
--- a/deps/v8/src/debug/debug-wasm-objects.cc
+++ b/deps/v8/src/debug/debug-wasm-objects.cc
@@ -697,6 +697,8 @@ class DebugWasmScopeIterator final : public debug::ScopeIterator {
ScopeType GetType() override { return type_; }
+ bool DeclaresLocals() override { return true; }
+
v8::Local<v8::Object> GetObject() override {
Isolate* isolate = frame_->isolate();
switch (type_) {
diff --git a/deps/v8/src/deoptimizer/deoptimizer.cc b/deps/v8/src/deoptimizer/deoptimizer.cc
index cddc0017959..95bde97653f 100644
--- a/deps/v8/src/deoptimizer/deoptimizer.cc
+++ b/deps/v8/src/deoptimizer/deoptimizer.cc
@@ -731,6 +731,13 @@ Deoptimizer::Deoptimizer(Isolate* isolate, Tagged<JSFunction> function,
DCHECK_WITH_SANDBOX_ACCESS(IsJSFunction(function));
CHECK(CodeKindCanDeoptimize(compiled_code_->kind()));
{
+ // Logging the deopt event prints the name and source position of the
+ // deoptimizing function, which are read from the in-sandbox
+ // SharedFunctionInfo and Script. This only affects the log output and
+ // cannot influence the deoptimization itself.
+ AllowSandboxAccess sandbox_access(
+ "Logging the deopt event reads the script name and source position of "
+ "the deoptimizing function.");
HandleScope scope(isolate_);
PROFILE(isolate_, CodeDeoptEvent(direct_handle(compiled_code_, isolate_),
kind, from_, fp_to_sp_delta_));
@@ -936,15 +943,9 @@ void Deoptimizer::TraceMarkForDeoptimization(Isolate* isolate,
DeoptimizeReasonToString(reason));
}
if (!v8_flags.log_deopt) return;
- no_gc.Release();
- {
- HandleScope handle_scope(isolate);
- PROFILE(isolate,
- CodeDependencyChangeEvent(
- direct_handle(code, isolate),
- direct_handle(deopt_data->GetSharedFunctionInfo(), isolate),
- DeoptimizeReasonToString(reason)));
- }
+ PROFILE(isolate,
+ CodeDependencyChangeEvent(code, deopt_data->GetSharedFunctionInfo(),
+ DeoptimizeReasonToString(reason)));
}
// static
diff --git a/deps/v8/src/diagnostics/disassembler.cc b/deps/v8/src/diagnostics/disassembler.cc
index 93903028029..f879fd5a1f2 100644
--- a/deps/v8/src/diagnostics/disassembler.cc
+++ b/deps/v8/src/diagnostics/disassembler.cc
@@ -493,13 +493,15 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
int Disassembler::Decode(Isolate* isolate, std::ostream& os, uint8_t* begin,
uint8_t* end, CodeReference code, Address current_pc,
size_t range_limit) {
- // Only the decoded range itself must be readable; a non-readable .text
- // section holds the embedded blob, so on-heap code is fine either way. With
- // no isolate the buffer is caller-owned and thus readable.
- DCHECK_WITH_MSG(v8_flags.text_is_readable || !isolate ||
- !OffHeapInstructionStream::PcIsOffHeap(
- isolate, reinterpret_cast<Address>(begin)),
- "Builtins disassembly requires a readable .text section");
+ // Only the decoded range must be readable, and a non-readable .text section
+ // holds just the embedded blob. On-heap code, and caller-owned buffers
+ // passed without an isolate, decode as usual.
+ if (!v8_flags.text_is_readable && isolate != nullptr &&
+ OffHeapInstructionStream::PcIsOffHeap(isolate,
+ reinterpret_cast<Address>(begin))) {
+ os << "<builtins disassembly requires a readable .text section>\n";
+ return 0;
+ }
V8NameConverter v8NameConverter(isolate, code);
if (isolate) {
// We have an isolate, so support external reference names from V8 and
diff --git a/deps/v8/src/diagnostics/objects-debug.cc b/deps/v8/src/diagnostics/objects-debug.cc
index 415f1befc23..01d15aff5cc 100644
--- a/deps/v8/src/diagnostics/objects-debug.cc
+++ b/deps/v8/src/diagnostics/objects-debug.cc
@@ -2176,12 +2176,12 @@ void JSShadowRealm::JSShadowRealmVerify(Isolate* isolate) {
#ifdef V8_INTL_SUPPORT
void JSLocale::JSLocaleVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsCppGCManagedBase(icu_locale()));
+ CHECK(IsForeign(icu_locale()));
}
void JSCollator::JSCollatorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsCppGCManagedBase(icu_collator()));
+ CHECK(IsForeign(icu_collator()));
CHECK(IsUndefined(bound_compare()) || IsJSFunction(bound_compare()));
CHECK(IsString(locale()));
}
@@ -2200,9 +2200,9 @@ void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsCppGCManagedBase(icu_locale_.load()));
- CHECK(IsCppGCManagedBase(icu_simple_date_format_.load()));
- CHECK(IsCppGCManagedBase(icu_date_interval_format_.load()));
+ CHECK(IsForeign(icu_locale_.load()));
+ CHECK(IsForeign(icu_simple_date_format_.load()));
+ CHECK(IsForeign(icu_date_interval_format_.load()));
CHECK(IsUndefined(bound_format()) || IsJSFunction(bound_format()));
CHECK(IsSmi(flags_.load()));
}
@@ -2217,21 +2217,21 @@ void JSDurationFormat::JSDurationFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsSmi(style_flags_.load()));
CHECK(IsSmi(display_flags_.load()));
- CHECK(IsCppGCManagedBase(icu_locale_.load()));
- CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
+ CHECK(IsForeign(icu_locale_.load()));
+ CHECK(IsForeign(icu_number_formatter_.load()));
}
void JSListFormat::JSListFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsCppGCManagedBase(icu_formatter_.load()));
+ CHECK(IsForeign(icu_formatter_.load()));
CHECK(IsSmi(flags_.load()));
}
void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
+ CHECK(IsForeign(icu_number_formatter_.load()));
CHECK(IsUndefined(bound_format()) || IsJSFunction(bound_format()));
}
@@ -2239,22 +2239,22 @@ void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
CHECK(IsSmi(flags_.load()));
- CHECK(IsCppGCManagedBase(icu_plural_rules_.load()));
- CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
+ CHECK(IsForeign(icu_plural_rules_.load()));
+ CHECK(IsForeign(icu_number_formatter_.load()));
}
void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
CHECK(IsString(numberingSystem()));
- CHECK(IsCppGCManagedBase(icu_formatter_.load()));
+ CHECK(IsForeign(icu_formatter_.load()));
CHECK(IsSmi(flags_.load()));
}
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsCppGCManagedBase(icu_break_iterator_.load()));
+ CHECK(IsForeign(icu_break_iterator_.load()));
CHECK(IsSmi(flags_.load()));
}
@@ -3431,17 +3431,22 @@ void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
CHECK(IsCell(wrapper_budget_.load()));
Object::VerifyPointer(isolate, packed_args_size_.load());
CHECK(IsSmi(packed_args_size_.load()));
- Tagged<Code> wrapper = wrapper_code(isolate);
- CHECK(wrapper->kind() == CodeKind::JS_TO_WASM_FUNCTION ||
- wrapper->kind() == CodeKind::C_WASM_ENTRY ||
- (wrapper->is_builtin() &&
- (wrapper->builtin_id() == Builtin::kJSToWasmWrapper ||
+ // The external JSFunction is attached after NewWasmExportedFunctionData
+ // finishes, so verify its wrapper code once attached.
+ Tagged<JSFunction> external;
+ if (internal()->try_get_external(&external)) {
+ Object::VerifyPointer(isolate, external);
+ Tagged<Code> wrapper = external->code(isolate);
+ CHECK(wrapper->kind() == CodeKind::JS_TO_WASM_FUNCTION ||
+ (wrapper->is_builtin() &&
+ (wrapper->builtin_id() == Builtin::kJSToWasmWrapper ||
#if V8_ENABLE_DRUMBRAKE
- wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapper ||
- wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapperAsm ||
+ wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapper ||
+ wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapperAsm ||
#endif // V8_ENABLE_DRUMBRAKE
- wrapper->builtin_id() == Builtin::kWasmPromising ||
- wrapper->builtin_id() == Builtin::kWasmStressSwitch)));
+ wrapper->builtin_id() == Builtin::kWasmPromising ||
+ wrapper->builtin_id() == Builtin::kWasmStressSwitch)));
+ }
}
void WasmCapiFunctionData::WasmCapiFunctionDataVerify(Isolate* isolate) {
diff --git a/deps/v8/src/diagnostics/objects-printer.cc b/deps/v8/src/diagnostics/objects-printer.cc
index a59c8453c98..96fb166732a 100644
--- a/deps/v8/src/diagnostics/objects-printer.cc
+++ b/deps/v8/src/diagnostics/objects-printer.cc
@@ -3518,10 +3518,8 @@ void WasmDispatchTableForImports::WasmDispatchTableForImportsPrint(
// Never called directly, as WasmFunctionData is an "abstract" class.
void WasmFunctionData::WasmFunctionDataPrint(std::ostream& os) {
- IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
os << "\n - func_ref: " << Brief(func_ref());
os << "\n - internal: " << Brief(internal());
- os << "\n - wrapper_code: " << Brief(wrapper_code(isolate));
os << "\n - js_promise_flags: " << js_promise_flags();
// No newline here; the caller prints it after printing additional fields.
}
@@ -3558,9 +3556,6 @@ void WasmImportData::WasmImportDataPrint(std::ostream& os) {
}
os << "\n - suspend: " << static_cast<int>(suspend());
os << "\n - wrapper_budget: " << wrapper_budget()->value();
- if (has_call_origin()) {
- os << "\n - call_origin: " << Brief(call_origin());
- }
os << "\n - sig: " << sig() << " (" << sig()->parameter_count() << " params, "
<< sig()->return_count() << " returns)";
os << "\n";
@@ -4202,10 +4197,8 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) {
os << "\n - has context extension slot";
}
- if (HasPositionInfo()) {
- os << "\n - start position: " << StartPosition();
- os << "\n - end position: " << EndPosition();
- }
+ os << "\n - start position: " << StartPosition();
+ os << "\n - end position: " << EndPosition();
os << "\n - length: " << length();
if (length() > 0) {
PrintScopeInfoList(this, os, "context slots", ContextLocalCount());
diff --git a/deps/v8/src/execution/execution.cc b/deps/v8/src/execution/execution.cc
index 74d96a8898e..e031b5db13e 100644
--- a/deps/v8/src/execution/execution.cc
+++ b/deps/v8/src/execution/execution.cc
@@ -344,7 +344,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate,
DCHECK(IsJSGlobalObject(function->context()->global_object()));
DirectHandle<Object> receiver = params.is_construct
- ? isolate->factory()->the_hole_value()
+ ? isolate->factory()->tdz_hole_value()
: params.receiver;
DirectHandle<FunctionTemplateInfo> fun_data(
function->shared()->api_func_data(), isolate);
diff --git a/deps/v8/src/execution/futex-emulation.cc b/deps/v8/src/execution/futex-emulation.cc
index 3d0c6913e2b..e30542ec997 100644
--- a/deps/v8/src/execution/futex-emulation.cc
+++ b/deps/v8/src/execution/futex-emulation.cc
@@ -342,10 +342,13 @@ class InSyncWaitScope {
} // namespace
#if V8_ENABLE_WEBASSEMBLY
+template <typename T>
+ requires(std::is_same_v<T, int32_t> || std::is_same_v<T, int64_t> ||
+ std::is_same_v<T, Tagged<Object>>)
Tagged<Object> FutexEmulation::WaitWasmManagedObject(
Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
- Tagged<Managed<FutexManagedObjectWaitList>> waitqueue,
- int32_t expected_value, int64_t rel_timeout_ns) {
+ Tagged<Managed<FutexManagedObjectWaitList>> waitqueue, T expected_value,
+ int64_t rel_timeout_ns) {
VMState<ATOMICS_WAIT> state(isolate);
base::TimeDelta rel_timeout =
base::TimeDelta::FromNanoseconds(rel_timeout_ns);
@@ -369,14 +372,33 @@ Tagged<Object> FutexEmulation::WaitWasmManagedObject(
Managed<FutexManagedObjectWaitList>::Ptr wait_list = waitqueue->ptr();
NoGarbageCollectionMutexGuard lock_guard(GetWaitList()->mutex());
- int32_t loaded_control_value =
- reinterpret_cast<std::atomic<int32_t>*>(object->address() + offset)
- ->load();
+ T loaded_control_value;
+ if constexpr (std::is_same_v<T, Tagged<Object>>) {
+ loaded_control_value = TaggedField<Object>::SeqCst_Load(object, offset);
+ } else {
+ loaded_control_value =
+ reinterpret_cast<std::atomic<T>*>(object->address() + offset)->load();
+ }
return *WaitSyncImpl<FutexManagedObjectWaitList>(
isolate, wait_list.raw(), node, lock_guard, use_timeout, timeout_time,
expected_value, loaded_control_value, {});
}
+
+template Tagged<Object> FutexEmulation::WaitWasmManagedObject<int32_t>(
+ Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
+ Tagged<Managed<FutexManagedObjectWaitList>> waitqueue,
+ int32_t expected_value, int64_t rel_timeout_ns);
+
+template Tagged<Object> FutexEmulation::WaitWasmManagedObject<int64_t>(
+ Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
+ Tagged<Managed<FutexManagedObjectWaitList>> waitqueue,
+ int64_t expected_value, int64_t rel_timeout_ns);
+
+template Tagged<Object> FutexEmulation::WaitWasmManagedObject<Tagged<Object>>(
+ Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
+ Tagged<Managed<FutexManagedObjectWaitList>> waitqueue,
+ Tagged<Object> expected_value, int64_t rel_timeout_ns);
#endif // V8_ENABLE_WEBASSEMBLY
template <typename T>
diff --git a/deps/v8/src/execution/futex-emulation.h b/deps/v8/src/execution/futex-emulation.h
index baad1a236ad..a5e134ef11c 100644
--- a/deps/v8/src/execution/futex-emulation.h
+++ b/deps/v8/src/execution/futex-emulation.h
@@ -247,10 +247,13 @@ class FutexEmulation : public AllStatic {
int64_t rel_timeout_ns);
#if V8_ENABLE_WEBASSEMBLY
+ template <typename T>
+ requires(std::is_same_v<T, int32_t> || std::is_same_v<T, int64_t> ||
+ std::is_same_v<T, Tagged<Object>>)
V8_EXPORT_PRIVATE static Tagged<Object> WaitWasmManagedObject(
Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
- Tagged<Managed<FutexManagedObjectWaitList>> waitqueue,
- int32_t expected_value, int64_t rel_timeout_ns);
+ Tagged<Managed<FutexManagedObjectWaitList>> waitqueue, T expected_value,
+ int64_t rel_timeout_ns);
#endif
// Wake |num_waiters_to_wake| threads that are waiting on the given |addr|.
diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc
index c834aac0043..7ef444669c8 100644
--- a/deps/v8/src/execution/isolate.cc
+++ b/deps/v8/src/execution/isolate.cc
@@ -1236,7 +1236,10 @@ class CallSiteBuilder {
DirectHandle<UnionOf<Smi, JSFunction>> function,
DirectHandle<Union<Code, BytecodeArray, Undefined>> code_obj,
int offset, int flags) {
- if (IsTheHole(*receiver_or_instance)) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*receiver_or_instance));
+#endif
+ if (IsTdzHole(*receiver_or_instance)) {
// TODO(jgruber): Fix all cases in which frames give us a hole value
// (e.g. the receiver in RegExp constructor frames).
receiver_or_instance = isolate_->factory()->undefined_value();
@@ -6886,6 +6889,17 @@ void Isolate::AbortConcurrentOptimization(BlockingBehavior behavior) {
#endif
}
+void Isolate::WaitForConcurrentOptimizationJobs() {
+ if (concurrent_recompilation_enabled()) {
+ optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
+ }
+#ifdef V8_ENABLE_MAGLEV
+ if (maglev_concurrent_dispatcher()->is_enabled()) {
+ maglev_concurrent_dispatcher()->AwaitCompileJobs();
+ }
+#endif // V8_ENABLE_MAGLEV
+}
+
std::shared_ptr<CompilationStatistics> Isolate::GetTurboStatistics() {
if (turbo_statistics_ == nullptr) {
turbo_statistics_.reset(new CompilationStatistics());
@@ -7679,8 +7693,7 @@ bool Isolate::HasCrashKeyStringCallbacks() {
return static_cast<bool>(allocate_crash_key_string_callback_);
}
-CrashKey Isolate::AddCrashKeyString(const char key[], CrashKeySize size,
- std::string_view value) {
+CrashKey Isolate::AllocateCrashKeyString(const char key[], CrashKeySize size) {
CHECK(HasCrashKeyStringCallbacks());
#if DEBUG
// Keys are limited in their length, see
@@ -7689,8 +7702,13 @@ CrashKey Isolate::AddCrashKeyString(const char key[], CrashKeySize size,
static constexpr size_t kCrashKeyStorageKeySize = 40;
DCHECK_LT(strlen(key), kCrashKeyStorageKeySize);
#endif // DEBUG
- CrashKey crash_key = allocate_crash_key_string_callback_(key, size);
- set_crash_key_string_callback_(crash_key, value);
+ return allocate_crash_key_string_callback_(key, size);
+}
+
+CrashKey Isolate::AddCrashKeyString(const char key[], CrashKeySize size,
+ std::string_view value) {
+ CrashKey crash_key = AllocateCrashKeyString(key, size);
+ SetCrashKeyString(crash_key, value);
return crash_key;
}
diff --git a/deps/v8/src/execution/isolate.h b/deps/v8/src/execution/isolate.h
index fab13a6a35b..f8c0c95e78f 100644
--- a/deps/v8/src/execution/isolate.h
+++ b/deps/v8/src/execution/isolate.h
@@ -514,6 +514,7 @@ using DebugObjectCache = std::vector<Handle<HeapObject>>;
wasm_custom_descriptors_enabled_callback, nullptr) \
V(IsJSApiWrapperNativeErrorCallback, \
is_js_api_wrapper_native_error_callback, nullptr) \
+ V(ArrayBufferDetachCallback, array_buffer_detach_callback, nullptr) \
/* State for Relocatable. */ \
V(Relocatable*, relocatable_top, nullptr) \
V(DebugObjectCache*, string_stream_debug_object_cache, nullptr) \
@@ -1797,6 +1798,11 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// compile dispatcher's queue.
void AbortConcurrentOptimization(BlockingBehavior blocking_behavior);
+ // Waits until all concurrent optimization jobs of this Isolate have
+ // finished. Finished jobs request an interrupt for installing their code, so
+ // they are finalized the next time interrupts are handled.
+ void WaitForConcurrentOptimizationJobs();
+
int id() const { return id_; }
bool was_locker_ever_used() const {
@@ -2121,6 +2127,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
}
}
+ v8::CrashKey AllocateCrashKeyString(const char key[], CrashKeySize size);
v8::CrashKey AddCrashKeyString(const char key[], CrashKeySize size,
std::string_view value);
void SetCrashKeyString(CrashKey crash_key, std::string_view value);
diff --git a/deps/v8/src/execution/microtask-queue.h b/deps/v8/src/execution/microtask-queue.h
index f13c994fc27..43d995c018e 100644
--- a/deps/v8/src/execution/microtask-queue.h
+++ b/deps/v8/src/execution/microtask-queue.h
@@ -108,6 +108,14 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
}
v8::MicrotasksPolicy microtasks_policy() const { return microtasks_policy_; }
+ // v8::MicrotaskQueue implementation of the above.
+ void SetMicrotasksPolicy(v8::MicrotasksPolicy policy) override {
+ set_microtasks_policy(policy);
+ }
+ v8::MicrotasksPolicy GetMicrotasksPolicy() const override {
+ return microtasks_policy();
+ }
+
intptr_t capacity() const { return capacity_; }
intptr_t size() const { return size_; }
intptr_t start() const { return start_; }
diff --git a/deps/v8/src/execution/tiering-manager.cc b/deps/v8/src/execution/tiering-manager.cc
index 655895570f9..f19871d36e8 100644
--- a/deps/v8/src/execution/tiering-manager.cc
+++ b/deps/v8/src/execution/tiering-manager.cc
@@ -4,8 +4,10 @@
#include "src/execution/tiering-manager.h"
+#include <algorithm>
#include <optional>
+#include "src/base/numerics/safe_conversions.h"
#include "src/base/platform/platform.h"
#include "src/baseline/baseline.h"
#include "src/codegen/assembler.h"
@@ -177,6 +179,21 @@ bool TiersUpToMaglev(std::optional<CodeKind> code_kind) {
return code_kind.has_value() && TiersUpToMaglev(code_kind.value());
}
+// Decrease times of interrupt budget underflow, the reason of not setting
+// to INT_MAX is the interrupt budget may overflow when doing add
+// operation for forward jump.
+constexpr int kMaxInterruptBudget = INT_MAX / 2;
+
+int ScaleInterruptBudget(int64_t invocations, int bytecode_length) {
+ int64_t budget = invocations * bytecode_length;
+ return static_cast<int>(std::clamp<int64_t>(budget, 0, kMaxInterruptBudget));
+}
+
+int ScaleInterruptBudget(double invocations, int bytecode_length) {
+ double budget = invocations * bytecode_length;
+ return std::clamp(base::saturated_cast<int>(budget), 0, kMaxInterruptBudget);
+}
+
int InterruptBudgetFor(Isolate* isolate, std::optional<CodeKind> code_kind,
Tagged<JSFunction> function,
CachedTieringDecision cached_tiering_decision,
@@ -195,7 +212,7 @@ int InterruptBudgetFor(Isolate* isolate, std::optional<CodeKind> code_kind,
// Avoid interrupts while we're already tiering.
if (tiering_in_progress && !osr_tiering_in_progress) {
- return INT_MAX / 2;
+ return kMaxInterruptBudget;
}
// Stretch loop interrupts while tiering is already in progress.
@@ -204,11 +221,12 @@ int InterruptBudgetFor(Isolate* isolate, std::optional<CodeKind> code_kind,
? v8_flags.invocation_count_for_osr_factor_while_tiering_in_progress
: 1;
if (maybe_tf_osr) {
- return osr_factor * v8_flags.invocation_count_for_osr * bytecode_length;
+ return ScaleInterruptBudget(osr_factor * v8_flags.invocation_count_for_osr,
+ bytecode_length);
}
if (maybe_ml_osr) {
- return osr_factor * v8_flags.invocation_count_for_maglev_osr *
- bytecode_length;
+ return ScaleInterruptBudget(
+ osr_factor * v8_flags.invocation_count_for_maglev_osr, bytecode_length);
}
if (TiersUpToMaglev(code_kind) &&
@@ -216,27 +234,32 @@ int InterruptBudgetFor(Isolate* isolate, std::optional<CodeKind> code_kind,
if (v8_flags.profile_guided_optimization) {
switch (cached_tiering_decision) {
case CachedTieringDecision::kDelayMaglev:
- return (std::max(v8_flags.invocation_count_for_maglev,
- v8_flags.minimum_invocations_after_ic_update) +
- v8_flags.invocation_count_for_maglev_with_delay) *
- bytecode_length;
+ return ScaleInterruptBudget(
+ int64_t{std::max(v8_flags.invocation_count_for_maglev,
+ v8_flags.minimum_invocations_after_ic_update)} +
+ v8_flags.invocation_count_for_maglev_with_delay,
+ bytecode_length);
case CachedTieringDecision::kEarlyMaglev:
case CachedTieringDecision::kEarlyTurbofan:
- return v8_flags.invocation_count_for_early_optimization *
- bytecode_length;
+ return ScaleInterruptBudget(
+ int64_t{v8_flags.invocation_count_for_early_optimization},
+ bytecode_length);
case CachedTieringDecision::kPending:
case CachedTieringDecision::kEarlySparkplug:
case CachedTieringDecision::kNormal:
- return v8_flags.invocation_count_for_maglev * bytecode_length;
+ return ScaleInterruptBudget(
+ int64_t{v8_flags.invocation_count_for_maglev}, bytecode_length);
}
// The enum value is coming from inside the sandbox and while the switch
// is exhaustive, it's not guaranteed that value is one of the declared
// values.
UNREACHABLE();
}
- return v8_flags.invocation_count_for_maglev * bytecode_length;
+ return ScaleInterruptBudget(int64_t{v8_flags.invocation_count_for_maglev},
+ bytecode_length);
}
- return v8_flags.invocation_count_for_turbofan * bytecode_length;
+ return ScaleInterruptBudget(int64_t{v8_flags.invocation_count_for_turbofan},
+ bytecode_length);
}
} // namespace
@@ -250,15 +273,14 @@ int TieringManager::InterruptBudgetFor(
function->shared()->GetBytecodeArray(isolate)->length();
if (FirstTimeTierUpToSparkplug(isolate, function)) {
- return bytecode_length * v8_flags.invocation_count_for_feedback_allocation;
+ return ScaleInterruptBudget(
+ int64_t{v8_flags.invocation_count_for_feedback_allocation},
+ bytecode_length);
}
DCHECK(function->has_feedback_vector());
if (bytecode_length > v8_flags.max_optimized_bytecode_size) {
- // Decrease times of interrupt budget underflow, the reason of not setting
- // to INT_MAX is the interrupt budget may overflow when doing add
- // operation for forward jump.
- return INT_MAX / 2;
+ return kMaxInterruptBudget;
}
return ::i::InterruptBudgetFor(
isolate,
@@ -438,7 +460,7 @@ OptimizationDecision TieringManager::ShouldOptimize(
if (isolate_->EfficiencyModeEnabled() &&
v8_flags.efficiency_mode_delay_turbofan_multiply &&
feedback_vector->invocation_count() <
- v8_flags.invocation_count_for_turbofan *
+ int64_t{v8_flags.invocation_count_for_turbofan} *
v8_flags.efficiency_mode_delay_turbofan_multiply) {
return OptimizationDecision::DoNotOptimize();
}
@@ -490,9 +512,11 @@ void TieringManager::NotifyICChanged(Tagged<FeedbackVector> vector) {
Tagged<SharedFunctionInfo> shared = vector->shared_function_info();
int bytecode_length = shared->GetBytecodeArray(isolate_)->length();
Tagged<FeedbackCell> cell = vector->parent_feedback_cell();
- int invocations = v8_flags.minimum_invocations_after_ic_update;
- int bytecodes = std::min(bytecode_length, (kMaxInt >> 1) / invocations);
- int new_budget = invocations * bytecodes;
+ int invocations =
+ std::max(1, v8_flags.minimum_invocations_after_ic_update.value());
+ int bytecodes = std::max(
+ 1, std::min(bytecode_length, kMaxInterruptBudget / invocations));
+ int new_budget = ScaleInterruptBudget(int64_t{invocations}, bytecodes);
int current_budget = cell->interrupt_budget();
if (v8_flags.profile_guided_optimization &&
shared->cached_tiering_decision() <=
@@ -507,21 +531,23 @@ void TieringManager::NotifyICChanged(Tagged<FeedbackVector> vector) {
if (vector->interrupt_budget_reset_by_ic_change()) {
// Initial interrupt budget is
// v8_flags.minimum_invocations_after_ic_update * bytecodes
- int new_consumed_budget = new_budget - current_budget;
+ int64_t new_consumed_budget = int64_t{new_budget} - current_budget;
new_invocation_count_before_stable =
vector->invocation_count_before_stable(kRelaxedLoad) +
- std::ceil(static_cast<float>(new_consumed_budget) / bytecodes);
+ base::saturated_cast<int>(std::ceil(
+ static_cast<double>(new_consumed_budget) / bytecodes));
} else {
// Initial interrupt budget is
// v8_flags.invocation_count_for_{maglev|turbofan} * bytecodes
- int total_consumed_budget =
- (maglev::IsMaglevEnabled()
- ? v8_flags.invocation_count_for_maglev
- : v8_flags.invocation_count_for_turbofan) *
+ int64_t total_consumed_budget =
+ int64_t{maglev::IsMaglevEnabled()
+ ? v8_flags.invocation_count_for_maglev
+ : v8_flags.invocation_count_for_turbofan} *
bytecodes -
current_budget;
new_invocation_count_before_stable =
- std::ceil(static_cast<float>(total_consumed_budget) / bytecodes);
+ base::saturated_cast<int>(std::ceil(
+ static_cast<double>(total_consumed_budget) / bytecodes));
}
if (new_invocation_count_before_stable >=
v8_flags.invocation_count_for_early_optimization) {
diff --git a/deps/v8/src/flags/feature-flags.h b/deps/v8/src/flags/feature-flags.h
index 18de3b8280e..5e9a1643f1c 100644
--- a/deps/v8/src/flags/feature-flags.h
+++ b/deps/v8/src/flags/feature-flags.h
@@ -84,6 +84,10 @@
"inline the Smi fast path of embedded feedback " \
"operations into JS baseline code") \
\
+ /* V8 side owner: leszeks */ \
+ INTERNAL_FEATURE(always_specialize_for_script_context, \
+ "always specialize for script contexts in optimized code") \
+ \
/* Instruction Tracing tool convention (early prototype, might change) */ \
/* Tool convention: https://github.com/WebAssembly/tool-conventions */ \
/* V8 side owner: jabraham */ \
@@ -141,11 +145,6 @@
/* V8 side owner: jkummerow */ \
WASM_FEATURE(imported_strings_utf8, "imported strings (utf8 features)") \
\
- /* Wide Arithmetic proposal */ \
- /* https://github.com/WebAssembly/wide-arithmetic */ \
- /* V8 side owner: ryandiaz */ \
- WASM_FEATURE(wide_arithmetic, "wide arithmetic") \
- \
/* Acquire-Release memory ordering from Shared-Everything Threads */ \
/* proposal. */ \
/* Part of https://github.com/WebAssembly/shared-everything-threads */ \
@@ -186,7 +185,13 @@
/* V8 side owner: jkummerow */ \
/* Staged in 15.4 */ \
IF_REVEC_ENABLED(INTERNAL_FEATURE, wasm_revectorize, \
- "128 to 256 bit SIMD re-vectorization for Wasm")
+ "128 to 256 bit SIMD re-vectorization for Wasm") \
+ \
+ /* Wide Arithmetic proposal */ \
+ /* https://github.com/WebAssembly/wide-arithmetic */ \
+ /* V8 side owner: ryandiaz */ \
+ /* Staged in 15.7 */ \
+ WASM_FEATURE(wide_arithmetic, "wide arithmetic")
// #############################################################################
// Shipped features (enabled by default).
@@ -227,6 +232,10 @@
WASM_FEATURE(legacy_eh, "legacy exception handling opcodes") \
\
IF_SPARKPLUG_PLUS_ENABLED(INTERNAL_FEATURE, sparkplug_plus, \
- "dynamic patching on JS baseline code")
+ "dynamic patching on JS baseline code") \
+ \
+ INTERNAL_FEATURE(homomorphic_ic, \
+ "Homomorphic IC state for same-handler highly polymorphic " \
+ "ICs")
#endif // V8_FLAGS_FEATURE_FLAGS_H_
diff --git a/deps/v8/src/flags/flag-definitions.h b/deps/v8/src/flags/flag-definitions.h
index a64f1b5e7b3..528cf0e9c05 100644
--- a/deps/v8/src/flags/flag-definitions.h
+++ b/deps/v8/src/flags/flag-definitions.h
@@ -257,9 +257,6 @@
#define DEFINE_DEBUG_BOOL DEFINE_BOOL_READONLY
#endif
-#define TEMPORARY_WASM_ALIAS_COMMENT \
- "temporary alias, to be dropped in V8 v15.3"
-
//
// Flags in all modes.
//
@@ -1718,15 +1715,17 @@ DEFINE_EXPERIMENTAL_FEATURE(turboshaft_typed_optimizations,
DEFINE_BOOL(wasm_simd_opt, true, "enable optimizations for Webassembly SIMD")
DEFINE_EXPERIMENTAL_FEATURE(future_wasm_simd_opt,
"enable extra optimizations for Webassembly SIMD")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_simd_opt, future_wasm_simd_opt,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_EXPERIMENTAL_FEATURE(wasm_deinterleave_loads,
"enable deinterleaving loads for Webassembly SIMD")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_deinterleave_loads,
- wasm_deinterleave_loads,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_IMPLICATION(future_wasm_simd_opt, wasm_simd_opt)
DEFINE_IMPLICATION(wasm_deinterleave_loads, wasm_simd_opt)
+#else
+DEFINE_BOOL_READONLY(wasm_simd_opt, false,
+ "enable optimizations for Webassembly SIMD")
+DEFINE_BOOL_READONLY(future_wasm_simd_opt, false,
+ "enable extra optimizations for Webassembly SIMD")
+DEFINE_BOOL_READONLY(wasm_deinterleave_loads, false,
+ "enable deinterleaving loads for Webassembly SIMD")
#endif // V8_TARGET_ARCH_ARM64
DEFINE_BOOL(turbolev, false,
@@ -1898,12 +1897,9 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
#define DECL_EXPERIMENTAL_JS_FLAG(feature_name, description) \
DEFINE_EXPERIMENTAL_FEATURE(feature_name, "enable " description " for JS")
#ifdef V8_ENABLE_WEBASSEMBLY
-#define DECL_EXPERIMENTAL_WASM_FLAG(feature_name, description) \
- DEFINE_EXPERIMENTAL_FEATURE(wasm_##feature_name, \
- "enable " description " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feature_name, \
- wasm_##feature_name, \
- TEMPORARY_WASM_ALIAS_COMMENT)
+#define DECL_EXPERIMENTAL_WASM_FLAG(feature_name, description) \
+ DEFINE_EXPERIMENTAL_FEATURE(wasm_##feature_name, \
+ "enable " description " for Wasm")
#else
#define DECL_EXPERIMENTAL_WASM_FLAG(feature_name, description)
#endif // V8_ENABLE_WEBASSEMBLY
@@ -1923,9 +1919,6 @@ FOREACH_EXPERIMENTAL_FEATURE_FLAG(DECL_EXPERIMENTAL_JS_FLAG,
#define DECL_PRE_STAGED_WASM_FLAG(feature_name, description) \
DEFINE_EXPERIMENTAL_FEATURE(wasm_##feature_name, \
"enable " description " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feature_name, \
- wasm_##feature_name, \
- TEMPORARY_WASM_ALIAS_COMMENT) \
DEFINE_IMPLICATION(experimental_fuzzing, wasm_##feature_name)
#else
#define DECL_PRE_STAGED_WASM_FLAG(feature_name, description)
@@ -1947,9 +1940,6 @@ FOREACH_PRE_STAGED_FEATURE_FLAG(DECL_PRE_STAGED_JS_FLAG,
#ifdef V8_ENABLE_WEBASSEMBLY
#define DECL_STAGED_WASM_FLAG(feature_name, description) \
DEFINE_BOOL(wasm_##feature_name, false, "enable " description " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feature_name, \
- wasm_##feature_name, \
- TEMPORARY_WASM_ALIAS_COMMENT) \
DEFINE_WEAK_IMPLICATION(wasm_staging, wasm_##feature_name)
#else
#define DECL_STAGED_WASM_FLAG(feature_name, description)
@@ -1969,11 +1959,8 @@ DEFINE_IMPLICATION(harmony, js_staging)
DEFINE_NEG_NEG_IMPLICATION(js_shipping, feature_name) \
DEFINE_NEG_NEG_IMPLICATION(harmony_shipping, feature_name)
#ifdef V8_ENABLE_WEBASSEMBLY
-#define DECL_SHIPPED_WASM_FLAG(feature_name, description) \
- DEFINE_BOOL(wasm_##feature_name, true, "enable " description " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feature_name, \
- wasm_##feature_name, \
- TEMPORARY_WASM_ALIAS_COMMENT)
+#define DECL_SHIPPED_WASM_FLAG(feature_name, description) \
+ DEFINE_BOOL(wasm_##feature_name, true, "enable " description " for Wasm")
#else
#define DECL_SHIPPED_WASM_FLAG(feature_name, description)
#endif // V8_ENABLE_WEBASSEMBLY
@@ -2102,14 +2089,10 @@ DEFINE_INT(wasm_debug_mask_for_testing, 0,
DEFINE_DEVELOPER_FLAG(
wasm_pgo_to_file,
"experimental: dump Wasm PGO information to a local file (for testing)")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_pgo_to_file, wasm_pgo_to_file,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_NEG_IMPLICATION(wasm_pgo_to_file, single_threaded)
DEFINE_DEVELOPER_FLAG(
wasm_pgo_from_file,
"experimental: read and use Wasm PGO data from a local file (for testing)")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_pgo_from_file,
- wasm_pgo_from_file, TEMPORARY_WASM_ALIAS_COMMENT)
#if V8_ENABLE_DRUMBRAKE
// Wasm is put into interpreter-only mode. We repeat flag implications down
@@ -2150,29 +2133,16 @@ DEFINE_SIZE_T(wasm_deopts_per_function_limit, 10,
DEFINE_TEST_ONLY_FLAG(
wasm_assume_ref_cast_succeeds,
"assume ref.cast always succeeds and skip the related type check")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_assume_ref_cast_succeeds,
- wasm_assume_ref_cast_succeeds,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_TEST_ONLY_FLAG(wasm_ref_cast_nop,
"enable unsafe ref.cast_nop instruction")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_ref_cast_nop,
- wasm_ref_cast_nop, TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_TEST_ONLY_FLAG(
wasm_skip_null_checks,
"skip null checks for call.ref and array and struct operations")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_skip_null_checks,
- wasm_skip_null_checks,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_TEST_ONLY_FLAG(wasm_skip_bounds_checks, "skip array bounds checks")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_skip_bounds_checks,
- wasm_skip_bounds_checks,
- TEMPORARY_WASM_ALIAS_COMMENT)
// Experimental variants of the Custom Descriptors prototype implementation.
DEFINE_EXPERIMENTAL_FEATURE(
wasm_js_interop, "enable JS Interop part of Custom Descriptors proposal")
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_js_interop, wasm_js_interop,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_IMPLICATION(wasm_js_interop, wasm_custom_descriptors)
DEFINE_BOOL(wasm_custom_descriptors_permitted, true,
"Emergency off-switch for Custom Descriptors Origin Trial")
@@ -2312,8 +2282,6 @@ DEFINE_DEBUG_BOOL(trace_wasm_instances, false,
// Flags for WASM SIMD256 revectorize
#ifdef V8_ENABLE_WASM_SIMD256_REVEC
-DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_revectorize, wasm_revectorize,
- TEMPORARY_WASM_ALIAS_COMMENT)
DEFINE_DEVELOPER_FLAG(trace_wasm_revectorize, "trace wasm revectorize")
#endif // V8_ENABLE_WASM_SIMD256_REVEC
@@ -2795,14 +2763,6 @@ DEFINE_BOOL(flush_baseline_code, false,
"flush of baseline code when it has not been executed recently")
DEFINE_BOOL(flush_bytecode, true,
"flush of bytecode when it has not been executed recently")
-DEFINE_INT(bytecode_old_age, 6, "number of gcs before we flush code")
-DEFINE_REQUIREMENT(v8_flags.bytecode_old_age >= 0)
-DEFINE_BOOL(flush_code_based_on_time, true,
- "Use time-base code flushing instead of age.")
-DEFINE_IMPLICATION(flush_code_based_on_time, late_heap_limit_check)
-DEFINE_BOOL(flush_code_based_on_tab_visibility, false,
- "Flush code when tab goes into the background.")
-DEFINE_IMPLICATION(flush_code_based_on_tab_visibility, late_heap_limit_check)
DEFINE_INT(bytecode_old_time, 180, "number of seconds before we flush code")
DEFINE_BOOL(stress_flush_code, false, "stress code flushing")
DEFINE_WEAK_IMPLICATION(stress_flush_code, flush_baseline_code)
@@ -2926,6 +2886,8 @@ DEFINE_BOOL_READONLY(debug_code, false, "")
DEFINE_BOOL_READONLY(trap_on_abort, true, "")
DEFINE_BOOL_READONLY(slow_debug_code, false, "")
#endif
+DEFINE_BOOL(enforce_x64_16byte_alignment, false,
+ "enforce 16-byte stack alignment on x64 platforms")
#ifdef V8_CODE_COMMENTS
DEFINE_BOOL(code_comments, false,
"emit comments in code disassembly; for more readable source "
@@ -3190,8 +3152,8 @@ DEFINE_EXPERIMENTAL_FEATURE(
DEFINE_IMPLICATION(parallel_compile_tasks_for_lazy, lazy_compile_dispatcher)
// cpu-profiler.cc
-DEFINE_INT(cpu_profiler_sampling_interval, 1000,
- "CPU profiler sampling interval in microseconds")
+DEFINE_UINT(cpu_profiler_sampling_interval, 1000,
+ "CPU profiler sampling interval in microseconds")
// debugger
DEFINE_BOOL(simulator_debugger, false,
@@ -3283,7 +3245,7 @@ DEFINE_GENERIC_IMPLICATION(
v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE))
DEFINE_BOOL_READONLY(fast_map_update, false,
"enable fast map update by caching the migration target")
-#define DEFAULT_MAX_POLYMORPHIC_MAP_COUNT 10
+#define DEFAULT_MAX_POLYMORPHIC_MAP_COUNT 4
DEFINE_INT(max_valid_polymorphic_map_count, DEFAULT_MAX_POLYMORPHIC_MAP_COUNT,
"maximum number of valid maps to track in POLYMORPHIC state")
DEFINE_BOOL(
@@ -3314,12 +3276,9 @@ DEFINE_BOOL(super_ic, true, "use an IC for super property loads")
DEFINE_EXPERIMENTAL_FEATURE(mega_dom_ic, "use MegaDOM IC state for API objects")
-DEFINE_BOOL(homomorphic_ic, false,
- "use Homomorphic IC state for same-handler highly polymorphic ICs")
DEFINE_UINT(homomorphic_ic_count, 8, "local cache size in homomorphic ICs")
DEFINE_REQUIREMENT(
base::bits::IsPowerOfTwo(v8_flags.homomorphic_ic_count.value()))
-DEFINE_IMPLICATION(future, homomorphic_ic)
// objects.cc
DEFINE_DEVELOPER_FLAG(trace_prototype_users,
@@ -4400,6 +4359,9 @@ DEFINE_IMPLICATION(disallow_unsafe_flags, wasm_stack_checks)
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags, max_wasm_functions)
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags,
wasm_max_initial_code_space_reservation)
+// Disable wasm_max_initial_code_space_reservation in fuzzing, as a wrong value
+// can lead to crashes.
+DEFINE_VALUE_IMPLICATION(fuzzing, wasm_max_initial_code_space_reservation, 0)
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags,
wasm_wrapper_tiering_budget)
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags,
@@ -4412,6 +4374,7 @@ DEFINE_IMPLICATION(disallow_unsafe_flags, enable_sse4_1)
DEFINE_IMPLICATION(disallow_unsafe_flags, enable_sse4_2)
// Features we don't currently want to fuzz.
DEFINE_NEG_IMPLICATION(disallow_unsafe_flags, cppgc_young_generation)
+DEFINE_NEG_IMPLICATION(disallow_unsafe_flags, enforce_x64_16byte_alignment)
DEFINE_NEG_IMPLICATION(disallow_unsafe_flags, test_only_unsafe)
// The memory corruption API is only allowed in sandbox testing/fuzzing mode.
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags &&
@@ -4553,8 +4516,6 @@ DEFINE_IMPLICATION(gdbjit, log)
#undef DEFINE_ALIAS_STRING
#undef DEFINE_ALIAS_FLOAT
-#undef TEMPORARY_WASM_ALIAS_COMMENT
-
#undef FLAG_MODE_DECLARE
#undef FLAG_MODE_DEFINE_DEFAULTS
#undef FLAG_MODE_META
diff --git a/deps/v8/src/handles/traced-handles-inl.h b/deps/v8/src/handles/traced-handles-inl.h
index 18ba0717aa1..dd1fc2b6f62 100644
--- a/deps/v8/src/handles/traced-handles-inl.h
+++ b/deps/v8/src/handles/traced-handles-inl.h
@@ -54,7 +54,7 @@ CppHeap* TracedHandles::GetCppHeapIfUnifiedYoungGC(Isolate* isolate) const {
// default.
if (!v8_flags.cppgc_young_generation) return nullptr;
auto* cpp_heap = CppHeap::From(isolate->heap()->cpp_heap());
- if (cpp_heap && cpp_heap->generational_gc_supported()) return cpp_heap;
+ if (cpp_heap->generational_gc_supported()) return cpp_heap;
return nullptr;
}
diff --git a/deps/v8/src/handles/traced-handles.cc b/deps/v8/src/handles/traced-handles.cc
index 765cf5216e0..077e28feef8 100644
--- a/deps/v8/src/handles/traced-handles.cc
+++ b/deps/v8/src/handles/traced-handles.cc
@@ -97,9 +97,9 @@ void TracedNodeBlock::FreeNode(TracedNode* node, Address zap_value) {
used_--;
}
-void SetSlotThreadSafe(Address** slot, Address* val) {
- reinterpret_cast<std::atomic<Address*>*>(slot)->store(
- val, std::memory_order_relaxed);
+void SetSlotThreadSafe(Address** slot, Address* val,
+ std::memory_order order = std::memory_order_relaxed) {
+ reinterpret_cast<std::atomic<Address*>*>(slot)->store(val, order);
}
void TracedHandles::RefillUsableNodeBlocks() {
@@ -201,13 +201,25 @@ void TracedHandles::Destroy(TracedNodeBlock& node_block, TracedNode& node) {
FreeNode(&node, kTracedHandleEagerResetZapValue);
}
+namespace {
+
+bool IsTracedHandleZapValue(Address value) {
+ CHECK_NE(kGlobalHandleZapValue, value);
+ return value == kTracedHandleEagerResetZapValue ||
+ value == kTracedHandleMinorGCResetZapValue ||
+ value == kTracedHandleMinorGCWeakResetZapValue ||
+ value == kTracedHandleFullGCResetZapValue;
+}
+
+} // namespace
+
void TracedHandles::Copy(const TracedNode& from_node, Address** to) {
- DCHECK_NE(kGlobalHandleZapValue, from_node.raw_object());
+ DCHECK(!IsTracedHandleZapValue(from_node.raw_object()));
FullObjectSlot o =
Create(from_node.raw_object(), reinterpret_cast<Address*>(to),
TracedReferenceStoreMode::kAssigningStore,
TracedReferenceHandling::kDefault);
- SetSlotThreadSafe(to, o.location());
+ SetSlotThreadSafe(to, o.location(), std::memory_order_release);
#ifdef VERIFY_HEAP
if (v8_flags.verify_heap) {
Object::ObjectVerify(Tagged<Object>(**to), isolate_);
@@ -221,8 +233,8 @@ void TracedHandles::Move(TracedNode& from_node, Address** from, Address** to) {
// Deal with old "to".
auto* to_node = TracedNode::FromLocation(*to);
DCHECK_IMPLIES(*to, to_node->is_in_use());
- DCHECK_IMPLIES(*to, kGlobalHandleZapValue != to_node->raw_object());
- DCHECK_NE(kGlobalHandleZapValue, from_node.raw_object());
+ DCHECK_IMPLIES(*to, !IsTracedHandleZapValue(to_node->raw_object()));
+ DCHECK(!IsTracedHandleZapValue(from_node.raw_object()));
if (*to) {
auto& to_node_block = TracedNodeBlock::From(*to_node);
Destroy(to_node_block, *to_node);
@@ -608,10 +620,9 @@ void TracedHandles::ProcessWeakYoungObjects(
auto* heap = isolate_->heap();
// ResetRoot() below should not trigger allocations in CppGC.
- if (auto* cpp_heap = CppHeap::From(heap->cpp_heap())) {
- cpp_heap->EnterDisallowGCScope();
- cpp_heap->EnterNoGCScope();
- }
+ auto* cpp_heap = CppHeap::From(heap->cpp_heap());
+ cpp_heap->EnterDisallowGCScope();
+ cpp_heap->EnterNoGCScope();
#ifdef DEBUG
size_t num_young_blocks = 0;
@@ -684,10 +695,8 @@ void TracedHandles::ProcessWeakYoungObjects(
DCHECK_GT(locally_freed, 0);
}
- if (auto* cpp_heap = CppHeap::From(isolate_->heap()->cpp_heap())) {
- cpp_heap->LeaveNoGCScope();
- cpp_heap->LeaveDisallowGCScope();
- }
+ cpp_heap->LeaveNoGCScope();
+ cpp_heap->LeaveDisallowGCScope();
}
void TracedHandles::Iterate(RootVisitor* visitor) {
@@ -842,9 +851,10 @@ bool TracedHandles::IsValidInUseNode(const Address* location) {
const TracedNode* node = TracedNode::FromLocation(location);
// This method is called after mark bits have been cleared.
DCHECK(!node->markbit());
- CHECK_IMPLIES(node->is_in_use(), node->raw_object() != kGlobalHandleZapValue);
- CHECK_IMPLIES(!node->is_in_use(),
- node->raw_object() == kGlobalHandleZapValue);
+ // Released nodes are zapped with one of the `kTracedHandle*ZapValue`s, see
+ // `TracedNodeBlock::FreeNode()`, and never with `kGlobalHandleZapValue`.
+ CHECK_IMPLIES(node->is_in_use(), !IsTracedHandleZapValue(node->raw_object()));
+ CHECK_IMPLIES(!node->is_in_use(), IsTracedHandleZapValue(node->raw_object()));
return node->is_in_use();
}
diff --git a/deps/v8/src/heap/concurrent-marking.cc b/deps/v8/src/heap/concurrent-marking.cc
index 1648ad6d95e..5ad7dac15df 100644
--- a/deps/v8/src/heap/concurrent-marking.cc
+++ b/deps/v8/src/heap/concurrent-marking.cc
@@ -377,9 +377,7 @@ void ConcurrentMarking::RunMajor(JobDelegate* delegate,
TaskState* task_state = task_state_[task_id].get();
auto* cpp_heap = CppHeap::From(heap_->cpp_heap());
MarkingWorklists::Local local_marking_worklists(
- marking_worklists_, cpp_heap
- ? cpp_heap->CreateCppMarkingState()
- : MarkingWorklists::Local::kNoCppMarkingState);
+ marking_worklists_, cpp_heap->CreateCppMarkingState());
WeakObjects::Local local_weak_objects(weak_objects_);
ConcurrentMarkingVisitor visitor(
&local_marking_worklists, &local_weak_objects, heap_, mark_compact_epoch,
diff --git a/deps/v8/src/heap/cppgc-internal/marker.cc b/deps/v8/src/heap/cppgc-internal/marker.cc
index 827a2e49fc4..2ee79d0b335 100644
--- a/deps/v8/src/heap/cppgc-internal/marker.cc
+++ b/deps/v8/src/heap/cppgc-internal/marker.cc
@@ -37,25 +37,22 @@ namespace internal {
namespace {
bool EnterIncrementalMarkingIfNeeded(MarkingConfig config, HeapBase& heap) {
- if (config.marking_type == MarkingConfig::MarkingType::kIncremental ||
- config.marking_type ==
- MarkingConfig::MarkingType::kIncrementalAndConcurrent) {
- WriteBarrier::FlagUpdater::Enter();
- heap.set_incremental_marking_in_progress(true);
- return true;
- }
- return false;
+ // Independent of the marking type, we arm the incremental bits. This allows
+ // for other systems to push objects onto marking worklists for later
+ // processing.
+ WriteBarrier::FlagUpdater::Enter();
+ heap.set_incremental_marking_in_progress(true);
+ return config.marking_type == MarkingConfig::MarkingType::kIncremental ||
+ config.marking_type ==
+ MarkingConfig::MarkingType::kIncrementalAndConcurrent;
}
bool ExitIncrementalMarkingIfNeeded(MarkingConfig config, HeapBase& heap) {
- if (config.marking_type == MarkingConfig::MarkingType::kIncremental ||
- config.marking_type ==
- MarkingConfig::MarkingType::kIncrementalAndConcurrent) {
- WriteBarrier::FlagUpdater::Exit();
- heap.set_incremental_marking_in_progress(false);
- return true;
- }
- return false;
+ WriteBarrier::FlagUpdater::Exit();
+ heap.set_incremental_marking_in_progress(false);
+ return config.marking_type == MarkingConfig::MarkingType::kIncremental ||
+ config.marking_type ==
+ MarkingConfig::MarkingType::kIncrementalAndConcurrent;
}
static constexpr size_t kDefaultDeadlineCheckInterval = 150u;
diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.cc b/deps/v8/src/heap/cppgc-js/cpp-heap.cc
index 120bcce5a11..c1de0c1c279 100644
--- a/deps/v8/src/heap/cppgc-js/cpp-heap.cc
+++ b/deps/v8/src/heap/cppgc-js/cpp-heap.cc
@@ -1018,7 +1018,23 @@ void CppHeap::CompactAndSweep() {
// The allocated bytes counter in v8 was reset to the current marked bytes, so
// any pending allocated bytes updates should be discarded.
buffered_allocated_bytes_ = 0;
- const size_t bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
+ size_t bytes_allocated_in_prefinalizers;
+ {
+ // Pre-finalizers may reset `TracedReference`s of objects that are about to
+ // be destroyed, either directly or through some method they invoke. Traced
+ // nodes of dead references have already been reclaimed in
+ // `TracedHandles::ResetDeadNodes()` in the atomic pause, so freeing them
+ // eagerly here would free the same node twice, corrupting the free list.
+ // Running pre-finalizers as sweeping on the mutator thread makes
+ // `TracedHandles::Destroy()` skip reclamation; still-in-use nodes are
+ // reclaimed in the next GC cycle instead.
+ std::optional<SweepingOnMutatorThreadForGlobalHandlesScope>
+ global_handles_scope;
+ if (isolate_) {
+ global_handles_scope.emplace(*isolate_->traced_handles());
+ }
+ bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
+ }
#if CPPGC_VERIFY_HEAP
UnifiedHeapMarkingVerifier verifier(*this, *collection_type_);
verifier.Run(stack_state_of_prev_gc(),
diff --git a/deps/v8/src/heap/cppgc-js/cpp-snapshot.cc b/deps/v8/src/heap/cppgc-js/cpp-snapshot.cc
index 6058cc88b83..172858a105f 100644
--- a/deps/v8/src/heap/cppgc-js/cpp-snapshot.cc
+++ b/deps/v8/src/heap/cppgc-js/cpp-snapshot.cc
@@ -674,11 +674,10 @@ void CppGraphBuilderImpl::Run() {
}
// static
-void CppGraphBuilder::Run(CppHeap* cpp_heap, HeapSnapshotGenerator* generator,
+void CppGraphBuilder::Run(CppHeap& cpp_heap, HeapSnapshotGenerator* generator,
CppHeapWrapperSet&& cpp_heap_wrappers) {
- CHECK_NOT_NULL(cpp_heap);
CHECK_NOT_NULL(generator);
- CppGraphBuilderImpl graph_builder(*cpp_heap, generator,
+ CppGraphBuilderImpl graph_builder(cpp_heap, generator,
std::move(cpp_heap_wrappers));
graph_builder.Run();
}
diff --git a/deps/v8/src/heap/cppgc-js/cpp-snapshot.h b/deps/v8/src/heap/cppgc-js/cpp-snapshot.h
index 3059fd34f22..5912ab6a31f 100644
--- a/deps/v8/src/heap/cppgc-js/cpp-snapshot.h
+++ b/deps/v8/src/heap/cppgc-js/cpp-snapshot.h
@@ -18,7 +18,7 @@ class V8_EXPORT_PRIVATE CppGraphBuilder final {
public:
// Add the C++ snapshot directly to the heap snapshot. See CppGraphBuilderImpl
// for algorithm internals.
- static void Run(v8::internal::CppHeap* cpp_heap,
+ static void Run(v8::internal::CppHeap& cpp_heap,
v8::internal::HeapSnapshotGenerator* generator,
CppHeapWrapperSet&& cpp_heap_wrappers);
diff --git a/deps/v8/src/heap/factory-base-inl.h b/deps/v8/src/heap/factory-base-inl.h
index 7066ff023d4..92064a4ec8f 100644
--- a/deps/v8/src/heap/factory-base-inl.h
+++ b/deps/v8/src/heap/factory-base-inl.h
@@ -29,6 +29,9 @@ namespace internal {
return isolate()->roots_table().name(); \
}
READ_ONLY_ROOT_LIST(RO_ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+RO_ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
#define MUTABLE_ROOT_ACCESSOR(Type, name, CamelName) \
diff --git a/deps/v8/src/heap/factory-base.cc b/deps/v8/src/heap/factory-base.cc
index debbaae2047..23bc6275501 100644
--- a/deps/v8/src/heap/factory-base.cc
+++ b/deps/v8/src/heap/factory-base.cc
@@ -891,6 +891,8 @@ MaybeHandle<SeqStringT> FactoryBase<Impl>::NewRawStringWithMap(
template <typename Impl>
MaybeHandle<SeqOneByteString> FactoryBase<Impl>::NewRawOneByteString(
uint32_t length, AllocationType allocation, AllocationHint hint) {
+ // TODO(manoskouk): This sometimes uses a shared allocation type. We might
+ // have to find its usages and add publish guards.
Tagged<Map> map = read_only_roots().seq_one_byte_string_map();
return NewRawStringWithMap<SeqOneByteString>(
length, map,
@@ -901,6 +903,8 @@ MaybeHandle<SeqOneByteString> FactoryBase<Impl>::NewRawOneByteString(
template <typename Impl>
MaybeHandle<SeqTwoByteString> FactoryBase<Impl>::NewRawTwoByteString(
uint32_t length, AllocationType allocation, AllocationHint hint) {
+ // TODO(manoskouk): This sometimes uses a shared allocation type. We might
+ // have to find its usages and add publish guards.
Tagged<Map> map = read_only_roots().seq_two_byte_string_map();
return NewRawStringWithMap<SeqTwoByteString>(
length, map,
diff --git a/deps/v8/src/heap/factory-base.h b/deps/v8/src/heap/factory-base.h
index 8ee1f9b9cc7..64ca10b0aaa 100644
--- a/deps/v8/src/heap/factory-base.h
+++ b/deps/v8/src/heap/factory-base.h
@@ -108,6 +108,9 @@ class FactoryBase {
#define ROOT_ACCESSOR(Type, name, CamelName) inline Handle<Type> name();
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+ ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
// Numbers (e.g. literals) are pretenured by the parser.
diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc
index 6390e956594..d2a5f284e01 100644
--- a/deps/v8/src/heap/factory.cc
+++ b/deps/v8/src/heap/factory.cc
@@ -371,6 +371,7 @@ DirectHandle<HeapObject> Factory::NewFillerObject(int size,
size, allocation, origin, alignment);
heap->CreateFillerObjectAt(result.address(), size,
ClearFreedMemoryMode{false}, allocation);
+ SharedObjectConditionalSafePublishGuard publish_guard(result, allocation);
return DirectHandle<HeapObject>(result, isolate());
}
@@ -897,7 +898,6 @@ MaybeHandle<String> NewStringFromBytes(Isolate* isolate, PeekBytes peek_bytes,
return isolate->factory()->LookupSingleCharacterStringFromCode(codepoint);
}
// Allocate string.
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
Handle<SeqOneByteString> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
@@ -905,18 +905,19 @@ MaybeHandle<String> NewStringFromBytes(Isolate* isolate, PeekBytes peek_bytes,
allocation));
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(*result, allocation);
decoder.Decode(result->GetChars(no_gc), peek_bytes());
return result;
}
// Allocate string.
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
Handle<SeqTwoByteString> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
StringPolicy::AllocateTwoByteString(
isolate, decoder.utf16_length(), allocation));
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(*result, allocation);
decoder.Decode(result->GetChars(no_gc), peek_bytes());
return result;
}
@@ -1144,6 +1145,8 @@ MaybeDirectHandle<String> Factory::WasmStringAddShared(
DirectHandle<SeqOneByteString> result =
NewRawSharedOneByteString(length).ToHandleChecked();
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(*result,
+ SharedFlag{true});
SharedStringAccessGuardIfNeeded access_guard(isolate());
uint8_t* dest = result->GetChars(no_gc, access_guard);
{
@@ -1433,6 +1436,8 @@ Handle<String> Factory::NewCopiedSubstringShared(DirectHandle<String> str,
Handle<SeqOneByteString> result =
NewRawSharedOneByteString(length).ToHandleChecked();
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(*result,
+ SharedFlag{true});
uint8_t* dest = result->GetChars(no_gc);
String::WriteToFlat(*str, dest, begin, length);
return result;
@@ -1440,6 +1445,8 @@ Handle<String> Factory::NewCopiedSubstringShared(DirectHandle<String> str,
Handle<SeqTwoByteString> result =
NewRawSharedTwoByteString(length).ToHandleChecked();
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(*result,
+ SharedFlag{true});
base::uc16* dest = result->GetChars(no_gc);
String::WriteToFlat(*str, dest, begin, length);
return result;
@@ -2186,20 +2193,11 @@ DirectHandle<WasmImportData> Factory::NewWasmImportData(
*importing_instance_data.ToHandleChecked());
}
result->set_wrapper_budget(*wrapper_budget_cell);
- result->clear_call_origin();
result->set_sig(sig);
result->clear_padding();
return direct_handle(result, isolate());
}
-DirectHandle<WasmImportData> Factory::NewWasmImportData(
- DirectHandle<WasmImportData> import_data) {
- return NewWasmImportData(
- handle(import_data->callable(), isolate()), import_data->suspend(),
- handle(import_data->importing_instance_data(), isolate()),
- import_data->sig());
-}
-
DirectHandle<WasmFastApiCallData> Factory::NewWasmFastApiCallData(
DirectHandle<HeapObject> signature, DirectHandle<Object> callback_data) {
Tagged<Map> map = *wasm_fast_api_call_data_map();
@@ -2322,7 +2320,6 @@ DirectHandle<WasmStackObject> Factory::NewWasmStackObject(
}
DirectHandle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
- DirectHandle<Code> export_wrapper,
DirectHandle<WasmTrustedInstanceData> instance_data,
DirectHandle<WasmFuncRef> func_ref,
DirectHandle<WasmInternalFunction> internal_function, int wrapper_budget,
@@ -2337,7 +2334,6 @@ DirectHandle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
DisallowGarbageCollection no_gc;
result->set_func_ref(*func_ref);
result->set_internal(*internal_function);
- result->set_wrapper_code(*export_wrapper);
result->set_instance_data(*instance_data);
result->set_function_index(func_index);
result->set_wrapper_budget(*wrapper_budget_cell);
@@ -2354,8 +2350,7 @@ DirectHandle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
DirectHandle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
Address call_target, DirectHandle<CppGCManagedBase> embedder_data,
- DirectHandle<Code> wrapper_code, DirectHandle<Map> rtt,
- const wasm::CanonicalSig* sig) {
+ DirectHandle<Map> rtt, const wasm::CanonicalSig* sig) {
DirectHandle<WasmImportData> import_data =
NewWasmImportData(undefined_value(), wasm::kNoSuspend,
DirectHandle<WasmTrustedInstanceData>(), sig);
@@ -2374,7 +2369,6 @@ DirectHandle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
DisallowGarbageCollection no_gc;
result->set_func_ref(*func_ref);
result->set_internal(*internal);
- result->set_wrapper_code(*wrapper_code);
result->set_embedder_data(*embedder_data);
result->set_js_promise_flags(
WasmFunctionData::SuspendField::encode(wasm::kNoSuspend) |
@@ -2406,9 +2400,9 @@ DirectHandle<WasmArray> Factory::NewWasmArray(wasm::ValueType element_type,
DirectHandle<Map> map,
AllocationType allocation,
WriteBarrierMode write_barrier) {
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
Tagged<WasmArray> result = NewWasmArrayUninitialized(length, map, allocation);
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(result, allocation);
if (element_type.is_numeric()) {
if (initial_value.zero_byte_representation()) {
memset(reinterpret_cast<void*>(result->ElementAddress(0)), 0,
@@ -2431,10 +2425,10 @@ DirectHandle<WasmArray> Factory::NewWasmArray(wasm::ValueType element_type,
DirectHandle<WasmArray> Factory::NewWasmArrayFromElements(
const wasm::ArrayType* type, base::Vector<wasm::WasmValue> elements,
DirectHandle<Map> map, AllocationType allocation) {
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
uint32_t length = static_cast<uint32_t>(elements.size());
Tagged<WasmArray> result = NewWasmArrayUninitialized(length, map, allocation);
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(result, allocation);
if (type->element_type().is_numeric()) {
for (uint32_t i = 0; i < length; i++) {
Address address = result->ElementAddress(i);
@@ -2454,9 +2448,9 @@ DirectHandle<WasmArray> Factory::NewWasmArrayFromMemory(
uint32_t length, DirectHandle<Map> map, AllocationType allocation,
wasm::CanonicalValueType element_type, base::Vector<const uint8_t> source) {
DCHECK(element_type.is_numeric());
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
Tagged<WasmArray> result = NewWasmArrayUninitialized(length, map, allocation);
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(result, allocation);
#if V8_TARGET_BIG_ENDIAN
MemCopyAndSwitchEndianness(reinterpret_cast<void*>(result->ElementAddress(0)),
source.data(), length,
@@ -2477,7 +2471,6 @@ DirectHandle<Object> Factory::NewWasmArrayFromElementSegment(
DirectHandle<Map> map, AllocationType allocation,
wasm::CanonicalValueType element_type) {
DCHECK(element_type.is_ref());
- SharedObjectConditionalSafePublishGuard publish_guard(allocation);
// If the element segment has not been initialized yet, lazily initialize it
// now.
@@ -2494,6 +2487,7 @@ DirectHandle<Object> Factory::NewWasmArrayFromElementSegment(
Tagged<WasmArray> result = NewWasmArrayUninitialized(length, map, allocation);
DisallowGarbageCollection no_gc;
+ SharedObjectConditionalSafePublishGuard publish_guard(result, allocation);
if (length > 0) {
WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
if (allocation == AllocationType::kYoung) wb_mode = SKIP_WRITE_BARRIER;
@@ -2560,16 +2554,18 @@ Handle<WasmCustomMap> Factory::NewWasmCustomMapUninitialized(
DirectHandle<WasmStruct> Factory::NewWasmStruct(const wasm::StructType* type,
wasm::WasmValue* args,
DirectHandle<Map> map) {
- SharedObjectConditionalSafePublishGuard publish_guard(type->is_shared());
AllocationAlignment alignment =
type->is_shared() ? kDoubleAligned : kTaggedAligned;
Tagged<HeapObject> raw = AllocateRaw(
WasmStruct::Size(type),
type->is_shared() ? AllocationType::kSharedOld : AllocationType::kYoung,
alignment);
+ DisallowGarbageCollection no_gc;
raw->set_map_after_allocation(isolate(), *map);
Tagged<WasmStruct> result = Cast<WasmStruct>(raw);
result->set_raw_properties_or_hash(*empty_fixed_array(), kRelaxedStore);
+ SharedObjectConditionalSafePublishGuard publish_guard(result,
+ type->is_shared());
for (uint32_t i = 0; i < type->field_count(); i++) {
int offset = type->field_offset(i);
if (type->field(i).is_numeric()) {
@@ -2734,7 +2730,6 @@ Handle<Map> Factory::NewMapImpl(MetaMapProviderFunc&& meta_map_provider,
int instance_size, ElementsKind elements_kind,
int inobject_properties,
AllocationType allocation_type) {
- SharedObjectConditionalSafePublishGuard publish_guard(allocation_type);
static_assert(LAST_JS_OBJECT_TYPE == LAST_TYPE);
DCHECK(!InstanceTypeChecker::MayHaveMapCheckFastCase(type));
DCHECK_IMPLIES(InstanceTypeChecker::IsJSObject(type) &&
@@ -5442,7 +5437,10 @@ Factory::JSFunctionBuilder::JSFunctionBuilder(
: isolate_(isolate), sfi_(sfi), context_(context) {}
Handle<JSFunction> Factory::JSFunctionBuilder::Build() {
- DirectHandle<Code> code(sfi_->GetCode(isolate_), isolate_);
+ DirectHandle<Code> code;
+ if (!maybe_code_.ToHandle(&code)) {
+ code = direct_handle(sfi_->GetCode(isolate_), isolate_);
+ }
// Retain the code across the call to BuildRaw, because it allocates and can
// trigger code to be flushed. Otherwise the SFI's compiled state and the
// function's compiled state can diverge, and the call to PostInstantiation
@@ -5606,9 +5604,10 @@ JSDispatchHandle Factory::NewJSDispatchHandle(uint16_t parameter_count,
DirectHandle<Code> code,
JSDispatchTable::Space* space) {
#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
- if (v8_flags.dispatch_table_gc_interval > 0) [[unlikely]] {
+ const int gc_interval = isolate()->heap()->dispatch_table_gc_interval();
+ if (gc_interval > 0) [[unlikely]] {
if (isolate()->heap()->increment_dispatch_table_allocations() %
- v8_flags.dispatch_table_gc_interval ==
+ gc_interval ==
0) {
isolate()->heap()->CollectAllGarbage(GCFlag::kNoFlags,
GarbageCollectionReason::kTesting);
diff --git a/deps/v8/src/heap/factory.h b/deps/v8/src/heap/factory.h
index ed01e3e68a0..ad5f09a08d9 100644
--- a/deps/v8/src/heap/factory.h
+++ b/deps/v8/src/heap/factory.h
@@ -869,10 +869,8 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
DirectHandle<Map> rtt);
DirectHandle<WasmCapiFunctionData> NewWasmCapiFunctionData(
Address call_target, DirectHandle<CppGCManagedBase> embedder_data,
- DirectHandle<Code> wrapper_code, DirectHandle<Map> rtt,
- const wasm::CanonicalSig* sig);
+ DirectHandle<Map> rtt, const wasm::CanonicalSig* sig);
DirectHandle<WasmExportedFunctionData> NewWasmExportedFunctionData(
- DirectHandle<Code> export_wrapper,
DirectHandle<WasmTrustedInstanceData> instance_data,
DirectHandle<WasmFuncRef> func_ref,
DirectHandle<WasmInternalFunction> internal_function, int wrapper_budget,
@@ -881,8 +879,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
DirectHandle<HeapObject> callable, wasm::Suspend suspend,
MaybeDirectHandle<WasmTrustedInstanceData> importing_instance_data,
const wasm::CanonicalSig* sig);
- DirectHandle<WasmImportData> NewWasmImportData(
- DirectHandle<WasmImportData> ref);
DirectHandle<WasmFastApiCallData> NewWasmFastApiCallData(
DirectHandle<HeapObject> signature, DirectHandle<Object> callback_data);
@@ -1279,6 +1275,12 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
maybe_feedback_cell_ = v;
return *this;
}
+ // Explicitly sets the initial Code object installed into the
+ // JSDispatchTable instead of querying SharedFunctionInfo::GetCode.
+ JSFunctionBuilder& set_code(DirectHandle<Code> v) {
+ maybe_code_ = v;
+ return *this;
+ }
private:
V8_WARN_UNUSED_RESULT Handle<JSFunction> BuildRaw(DirectHandle<Code> code);
@@ -1288,6 +1290,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
DirectHandle<Context> context_;
MaybeDirectHandle<Map> maybe_map_;
MaybeDirectHandle<FeedbackCell> maybe_feedback_cell_;
+ MaybeDirectHandle<Code> maybe_code_;
AllocationType allocation_type_ = AllocationType::kOld;
friend class Factory;
diff --git a/deps/v8/src/heap/gc-tracer.cc b/deps/v8/src/heap/gc-tracer.cc
index a58125730eb..9935caf7909 100644
--- a/deps/v8/src/heap/gc-tracer.cc
+++ b/deps/v8/src/heap/gc-tracer.cc
@@ -605,7 +605,7 @@ void GCTracer::StopCycle(GarbageCollector collector) {
void GCTracer::StopFullCycleIfFinished() {
if (current_.state != Event::State::SWEEPING) return;
if (!notified_full_sweeping_completed_) return;
- if (heap_->cpp_heap() && !notified_full_cppgc_completed_) return;
+ if (!notified_full_cppgc_completed_) return;
StopCycle(GarbageCollector::MARK_COMPACTOR);
notified_full_sweeping_completed_ = false;
notified_full_cppgc_completed_ = false;
@@ -617,8 +617,7 @@ void GCTracer::StopYoungCycleIfFinished() {
if (current_.state != Event::State::SWEEPING) return;
if (!notified_young_sweeping_completed_) return;
// Check if young cppgc was scheduled but hasn't completed yet.
- if (heap_->cpp_heap() && notified_young_cppgc_running_ &&
- !notified_young_cppgc_completed_) {
+ if (notified_young_cppgc_running_ && !notified_young_cppgc_completed_) {
return;
}
bool was_young_gc_during_full_gc_sweeping_ =
@@ -661,8 +660,8 @@ void GCTracer::NotifyFullSweepingCompletedAndStopCycleIfFinished() {
DCHECK(current_.state == Event::State::SWEEPING ||
current_.state == Event::State::ATOMIC);
- // Stop a full GC cycle only when both v8 and cppgc (if available) GCs have
- // finished sweeping. This method is invoked by v8.
+ // Stop a full GC cycle only when both v8 and cppgc GCs have finished
+ // sweeping. This method is invoked by v8.
if (v8_flags.trace_gc_freelists) {
PrintIsolate(heap_->isolate(),
"FreeLists statistics after sweeping completed:\n");
@@ -697,9 +696,8 @@ void GCTracer::NotifyYoungSweepingCompletedAndStopCycleIfFinished() {
}
void GCTracer::NotifyFullCppGCCompleted() {
- // Stop a full GC cycle only when both v8 and cppgc (if available) GCs have
- // finished sweeping. This method is invoked by cppgc.
- DCHECK(heap_->cpp_heap());
+ // Stop a full GC cycle only when both v8 and cppgc GCs have finished
+ // sweeping. This method is invoked by cppgc.
const auto* metric_recorder =
CppHeap::From(heap_->cpp_heap())->GetMetricRecorder();
USE(metric_recorder);
@@ -717,9 +715,8 @@ void GCTracer::NotifyFullCppGCCompleted() {
}
void GCTracer::NotifyYoungCppGCCompleted() {
- // Stop a young GC cycle only when both v8 and cppgc (if available) GCs have
- // finished sweeping. This method is invoked by cppgc.
- DCHECK(heap_->cpp_heap());
+ // Stop a young GC cycle only when both v8 and cppgc GCs have finished
+ // sweeping. This method is invoked by cppgc.
DCHECK(notified_young_cppgc_running_);
const auto* metric_recorder =
CppHeap::From(heap_->cpp_heap())->GetMetricRecorder();
@@ -1619,17 +1616,14 @@ void GCTracer::ReportFullCycleToRecorder() {
DCHECK(!Event::IsYoungGenerationEvent(current_.type));
DCHECK_EQ(Event::State::NOT_RUNNING, current_.state);
auto* cpp_heap = v8::internal::CppHeap::From(heap_->cpp_heap());
- DCHECK_IMPLIES(cpp_heap,
- cpp_heap->GetMetricRecorder()->FullGCMetricsReportPending());
+ DCHECK(cpp_heap->GetMetricRecorder()->FullGCMetricsReportPending());
const std::shared_ptr<metrics::Recorder>& recorder =
heap_->isolate()->metrics_recorder();
DCHECK_NOT_NULL(recorder);
if (!recorder->HasEmbedderRecorder()) {
incremental_mark_batched_events_ = {};
incremental_sweep_batched_events_ = {};
- if (cpp_heap) {
- cpp_heap->GetMetricRecorder()->ClearCachedEvents();
- }
+ cpp_heap->GetMetricRecorder()->ClearCachedEvents();
return;
}
if (!incremental_mark_batched_events_.events.empty()) {
@@ -1650,47 +1644,42 @@ void GCTracer::ReportFullCycleToRecorder() {
event.is_input_handling = current_.is_input_handling;
// Managed C++ heap statistics:
- if (cpp_heap) {
- cpp_heap->GetMetricRecorder()->FlushBatchedIncrementalEvents();
- const std::optional<cppgc::internal::MetricRecorder::GCCycle>
- optional_cppgc_event =
- cpp_heap->GetMetricRecorder()->ExtractLastFullGcEvent();
- DCHECK(optional_cppgc_event.has_value());
- DCHECK(!cpp_heap->GetMetricRecorder()->FullGCMetricsReportPending());
- const cppgc::internal::MetricRecorder::GCCycle& cppgc_event =
- optional_cppgc_event.value();
- DCHECK_EQ(cppgc_event.type,
- cppgc::internal::MetricRecorder::GCCycle::Type::kMajor);
- CopyTimeMetrics(event.total_cpp, cppgc_event.total);
- CopyTimeMetrics(event.main_thread_cpp, cppgc_event.main_thread);
- CopyTimeMetrics(event.main_thread_atomic_cpp,
- cppgc_event.main_thread_atomic);
- CopyTimeMetrics(event.main_thread_incremental_cpp,
- cppgc_event.main_thread_incremental);
- CopySizeMetrics(event.objects_cpp, cppgc_event.objects);
- CopySizeMetrics(event.memory_cpp, cppgc_event.memory);
- DCHECK_NE(-1, cppgc_event.collection_rate_in_percent);
- event.collection_rate_cpp_in_percent =
- cppgc_event.collection_rate_in_percent;
- DCHECK_NE(-1, cppgc_event.efficiency_in_bytes_per_us);
- event.efficiency_cpp_in_bytes_per_us =
- cppgc_event.efficiency_in_bytes_per_us;
- DCHECK_NE(-1, cppgc_event.main_thread_efficiency_in_bytes_per_us);
- event.main_thread_efficiency_cpp_in_bytes_per_us =
- cppgc_event.main_thread_efficiency_in_bytes_per_us;
-
- if (total_duration_since_last_mark_compact_.IsZero()) {
- event.collection_weight_cpp_in_percent = 0;
- event.main_thread_collection_weight_cpp_in_percent = 0;
- } else {
- event.collection_weight_cpp_in_percent =
- static_cast<double>(event.total_cpp.total_wall_clock_duration_in_us) /
- total_duration_since_last_mark_compact_.InMicroseconds();
- event.main_thread_collection_weight_cpp_in_percent =
- static_cast<double>(
- event.main_thread_cpp.total_wall_clock_duration_in_us) /
- total_duration_since_last_mark_compact_.InMicroseconds();
- }
+ cpp_heap->GetMetricRecorder()->FlushBatchedIncrementalEvents();
+ const std::optional<cppgc::internal::MetricRecorder::GCCycle>
+ optional_cppgc_event =
+ cpp_heap->GetMetricRecorder()->ExtractLastFullGcEvent();
+ DCHECK(optional_cppgc_event.has_value());
+ DCHECK(!cpp_heap->GetMetricRecorder()->FullGCMetricsReportPending());
+ const cppgc::internal::MetricRecorder::GCCycle& cppgc_event =
+ optional_cppgc_event.value();
+ DCHECK_EQ(cppgc_event.type,
+ cppgc::internal::MetricRecorder::GCCycle::Type::kMajor);
+ CopyTimeMetrics(event.total_cpp, cppgc_event.total);
+ CopyTimeMetrics(event.main_thread_cpp, cppgc_event.main_thread);
+ CopyTimeMetrics(event.main_thread_atomic_cpp, cppgc_event.main_thread_atomic);
+ CopyTimeMetrics(event.main_thread_incremental_cpp,
+ cppgc_event.main_thread_incremental);
+ CopySizeMetrics(event.objects_cpp, cppgc_event.objects);
+ CopySizeMetrics(event.memory_cpp, cppgc_event.memory);
+ DCHECK_NE(-1, cppgc_event.collection_rate_in_percent);
+ event.collection_rate_cpp_in_percent = cppgc_event.collection_rate_in_percent;
+ DCHECK_NE(-1, cppgc_event.efficiency_in_bytes_per_us);
+ event.efficiency_cpp_in_bytes_per_us = cppgc_event.efficiency_in_bytes_per_us;
+ DCHECK_NE(-1, cppgc_event.main_thread_efficiency_in_bytes_per_us);
+ event.main_thread_efficiency_cpp_in_bytes_per_us =
+ cppgc_event.main_thread_efficiency_in_bytes_per_us;
+
+ if (total_duration_since_last_mark_compact_.IsZero()) {
+ event.collection_weight_cpp_in_percent = 0;
+ event.main_thread_collection_weight_cpp_in_percent = 0;
+ } else {
+ event.collection_weight_cpp_in_percent =
+ static_cast<double>(event.total_cpp.total_wall_clock_duration_in_us) /
+ total_duration_since_last_mark_compact_.InMicroseconds();
+ event.main_thread_collection_weight_cpp_in_percent =
+ static_cast<double>(
+ event.main_thread_cpp.total_wall_clock_duration_in_us) /
+ total_duration_since_last_mark_compact_.InMicroseconds();
}
// Unified heap statistics:
@@ -1850,17 +1839,15 @@ void GCTracer::ReportIncrementalMarkingStepToRecorder(double v8_duration) {
DCHECK_NOT_NULL(recorder);
if (!recorder->HasEmbedderRecorder()) return;
incremental_mark_batched_events_.events.emplace_back();
- if (heap_->cpp_heap()) {
- const std::optional<
- cppgc::internal::MetricRecorder::MainThreadIncrementalMark>
- cppgc_event = v8::internal::CppHeap::From(heap_->cpp_heap())
- ->GetMetricRecorder()
- ->ExtractLastIncrementalMarkEvent();
- if (cppgc_event.has_value()) {
- DCHECK_NE(-1, cppgc_event.value().duration_us);
- incremental_mark_batched_events_.events.back()
- .cpp_wall_clock_duration_in_us = cppgc_event.value().duration_us;
- }
+ const std::optional<
+ cppgc::internal::MetricRecorder::MainThreadIncrementalMark>
+ cppgc_event = v8::internal::CppHeap::From(heap_->cpp_heap())
+ ->GetMetricRecorder()
+ ->ExtractLastIncrementalMarkEvent();
+ if (cppgc_event.has_value()) {
+ DCHECK_NE(-1, cppgc_event.value().duration_us);
+ incremental_mark_batched_events_.events.back()
+ .cpp_wall_clock_duration_in_us = cppgc_event.value().duration_us;
}
incremental_mark_batched_events_.events.back().wall_clock_duration_in_us =
static_cast<int64_t>(v8_duration *
@@ -1894,9 +1881,7 @@ void GCTracer::ReportYoungCycleToRecorder() {
DCHECK_NOT_NULL(recorder);
auto* cpp_heap = v8::internal::CppHeap::From(heap_->cpp_heap());
if (!recorder->HasEmbedderRecorder()) {
- if (cpp_heap) {
- cpp_heap->GetMetricRecorder()->ClearCachedYoungEvents();
- }
+ cpp_heap->GetMetricRecorder()->ClearCachedYoungEvents();
return;
}
@@ -1906,7 +1891,7 @@ void GCTracer::ReportYoungCycleToRecorder() {
event.priority = current_.priority;
#if defined(CPPGC_YOUNG_GENERATION)
// Managed C++ heap statistics:
- if (cpp_heap && cpp_heap->generational_gc_supported()) {
+ if (cpp_heap->generational_gc_supported()) {
auto* metric_recorder = cpp_heap->GetMetricRecorder();
const std::optional<cppgc::internal::MetricRecorder::GCCycle>
optional_cppgc_event = metric_recorder->ExtractLastYoungGcEvent();
diff --git a/deps/v8/src/heap/heap-write-barrier-inl.h b/deps/v8/src/heap/heap-write-barrier-inl.h
index 2ef9a93b50a..5ca5b0a8d66 100644
--- a/deps/v8/src/heap/heap-write-barrier-inl.h
+++ b/deps/v8/src/heap/heap-write-barrier-inl.h
@@ -13,6 +13,7 @@
// Clients of this interface shouldn't depend on lots of heap internals.
// Do not include anything from src/heap here!
+#include "src/heap/base-page-inl.h"
#include "src/heap/heap-layout-inl.h"
#include "src/heap/marking-barrier.h"
#include "src/heap/memory-chunk.h"
@@ -237,12 +238,13 @@ void WriteBarrier::ForEphemeronHashTable(Tagged<EphemeronHashTable> host,
// static
void WriteBarrier::ForExternalPointer(Tagged<HeapObject> host,
ExternalPointerSlot slot,
+ ExternalPointerHandle handle,
WriteBarrierMode mode) {
if (mode == SKIP_WRITE_BARRIER) {
SLOW_DCHECK(HeapLayout::InYoungGeneration(host));
return;
}
- Marking(host, slot);
+ Marking(host, slot, handle);
}
// static
@@ -424,11 +426,12 @@ void WriteBarrier::ForArrayBufferExtension(Tagged<JSArrayBuffer> host,
MarkingSlow(host, extension);
}
-void WriteBarrier::Marking(Tagged<HeapObject> host, ExternalPointerSlot slot) {
+void WriteBarrier::Marking(Tagged<HeapObject> host, ExternalPointerSlot slot,
+ ExternalPointerHandle handle) {
if (!IsMarking(host)) [[likely]] {
return;
}
- MarkingSlow(host, slot);
+ MarkingSlow(host, slot, handle);
}
void WriteBarrier::Marking(Tagged<HeapObject> host, IndirectPointerSlot slot) {
@@ -465,41 +468,43 @@ void WriteBarrier::MarkingFromTracedHandle(Tagged<Object> value) {
// static
void WriteBarrier::ForCppHeapPointer(Tagged<CppHeapPointerWrapperObjectT> host,
CppHeapPointerSlot slot, void* value) {
- // Note: this is currently a combined barrier for marking both the
- // CppHeapPointerTable entry and the referenced object.
+ // This is currently a combined barrier for marking both CppHeapPointerTable
+ // entry and the `value` object.
- if (!IsMarking(host)) [[likely]] {
+ // The global write barrier guard is always armed when the young generation is
+ // enabled for CppHeap. We must base these checks on trusted data to avoid
+ // desync between table entry and value object.
+ if (!cppgc::internal::WriteBarrier::IsEnabled()) [[likely]] {
+ return;
+ }
+
+ MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
+
+ // The global check is probabilistic and we need an exact check here.
+ if (marking_barrier->is_not_major()) [[likely]] {
#if defined(CPPGC_YOUNG_GENERATION)
// There is no young-gen CppHeapPointerTable space so we should not mark
// the table entry in this case.
- if (value) {
- GenerationalBarrierForCppHeapPointer(host, value);
- }
+ GenerationalBarrierForCppHeapPointer(marking_barrier->heap(), host, value);
#endif
return;
}
- MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
- if (marking_barrier->is_minor()) {
- // TODO(v8:13012): We do not currently mark Oilpan objects while MinorMS is
- // active. Once Oilpan uses a generational GC with incremental marking and
- // unified heap, this barrier will be needed again.
- return;
- }
-
+ // Marking for a full GC is enabled.
MarkingSlowFromCppHeapWrappable(marking_barrier->heap(), host, slot, value);
}
// static
void WriteBarrier::GenerationalBarrierForCppHeapPointer(
- Tagged<CppHeapPointerWrapperObjectT> host, void* value) {
+ Heap* heap, Tagged<CppHeapPointerWrapperObjectT> host, void* value) {
if (!value) {
return;
}
- auto* memory_chunk = MemoryChunk::FromHeapObject(host);
- if (V8_LIKELY(HeapLayout::InYoungGeneration(memory_chunk, host))) {
+ auto* page = BasePage::FromHeapObject(host);
+ const AllocationSpace space_id = page->owner_identity();
+ if (V8_LIKELY(space_id == NEW_SPACE || space_id == NEW_LO_SPACE)) {
return;
}
- auto* cpp_heap = memory_chunk->Metadata()->heap()->cpp_heap();
+ auto* cpp_heap = heap->cpp_heap();
v8::internal::CppHeap::From(cpp_heap)->RememberCrossHeapReferenceIfNeeded(
host, value);
}
diff --git a/deps/v8/src/heap/heap-write-barrier.cc b/deps/v8/src/heap/heap-write-barrier.cc
index f40c7c22abc..7c38e745cd1 100644
--- a/deps/v8/src/heap/heap-write-barrier.cc
+++ b/deps/v8/src/heap/heap-write-barrier.cc
@@ -65,12 +65,14 @@ void WriteBarrier::MarkingSlowFromTracedHandle(Tagged<HeapObject> value) {
marking_barrier->WriteWithoutHost(value);
}
+// This is currently a combined barrier for marking both the CppHeapPointerTable
+// entry and the referenced object (if any).
+//
// static
void WriteBarrier::MarkingSlowFromCppHeapWrappable(
Heap* heap, Tagged<CppHeapPointerWrapperObjectT> host,
CppHeapPointerSlot slot, void* object) {
- // Note: this is currently a combined barrier for marking both the
- // CppHeapPointerTable entry and the referenced object (if any).
+ DCHECK(heap->cpp_heap());
#ifdef V8_COMPRESS_POINTERS
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
@@ -87,7 +89,7 @@ void WriteBarrier::MarkingSlowFromCppHeapWrappable(
reinterpret_cast<Address>(object));
#endif // V8_COMPRESS_POINTERS
- if (heap->cpp_heap() && object) {
+ if (object) {
CppHeap::From(heap->cpp_heap())->WriteBarrier(object);
}
}
@@ -139,10 +141,13 @@ void WriteBarrier::MarkingSlow(Tagged<JSArrayBuffer> host,
}
void WriteBarrier::MarkingSlow(Tagged<HeapObject> host,
- ExternalPointerSlot slot) {
+ ExternalPointerSlot slot,
+ ExternalPointerHandle handle) {
#ifdef V8_COMPRESS_POINTERS
if (!slot.HasExternalPointerHandle()) return;
+ DCHECK_EQ(handle, slot.Relaxed_LoadHandle());
+
MarkingBarrier* marking_barrier = CurrentMarkingBarrier(host);
IsolateForPointerCompression isolate(marking_barrier->heap()->isolate());
@@ -152,7 +157,6 @@ void WriteBarrier::MarkingSlow(Tagged<HeapObject> host,
isolate.GetExternalPointerTableSpaceFor(slot.tag_range(), host.address());
DCHECK(!space->is_internal_read_only_space());
- ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
table.Mark(space, handle, slot.address(), slot.tag_range());
if (marking_barrier->is_minor() && HeapLayout::InYoungGeneration(host)) {
diff --git a/deps/v8/src/heap/heap-write-barrier.h b/deps/v8/src/heap/heap-write-barrier.h
index 1290d87f1cc..1928d0d64d9 100644
--- a/deps/v8/src/heap/heap-write-barrier.h
+++ b/deps/v8/src/heap/heap-write-barrier.h
@@ -101,6 +101,7 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
ArrayBufferExtension* extension);
static inline void ForExternalPointer(
Tagged<HeapObject> host, ExternalPointerSlot slot,
+ ExternalPointerHandle handle,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
static inline void ForIndirectPointer(
Tagged<HeapObject> host, IndirectPointerSlot slot,
@@ -198,7 +199,8 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
Tagged<MaybeObject> value);
static inline void MarkingForRelocInfo(Tagged<InstructionStream> host,
RelocInfo*, Tagged<HeapObject> value);
- static inline void Marking(Tagged<HeapObject> host, ExternalPointerSlot slot);
+ static inline void Marking(Tagged<HeapObject> host, ExternalPointerSlot slot,
+ ExternalPointerHandle handle);
static inline void Marking(Tagged<HeapObject> host, IndirectPointerSlot slot);
static inline void Marking(Tagged<TrustedObject> host,
ProtectedPointerSlot slot,
@@ -213,7 +215,8 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
V8_NOINLINE V8_PRESERVE_MOST static void MarkingSlow(
Tagged<JSArrayBuffer> host, ArrayBufferExtension*);
V8_NOINLINE V8_PRESERVE_MOST static void MarkingSlow(
- Tagged<HeapObject> host, ExternalPointerSlot slot);
+ Tagged<HeapObject> host, ExternalPointerSlot slot,
+ ExternalPointerHandle handle);
V8_NOINLINE V8_PRESERVE_MOST static void MarkingSlow(
Tagged<HeapObject> host, IndirectPointerSlot slot);
V8_NOINLINE V8_PRESERVE_MOST static void MarkingSlow(
@@ -230,7 +233,7 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
V8_NOINLINE V8_PRESERVE_MOST static void GenerationalBarrierSlow(
Tagged<HeapObject> object, Address slot, Tagged<HeapObject> value);
static inline void GenerationalBarrierForCppHeapPointer(
- Tagged<CppHeapPointerWrapperObjectT> host, void* value);
+ Heap* heap, Tagged<CppHeapPointerWrapperObjectT> host, void* value);
V8_NOINLINE V8_PRESERVE_MOST static void SharedSlow(
Tagged<TrustedObject> host, ProtectedPointerSlot slot,
diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc
index d67b6933c72..420c631486d 100644
--- a/deps/v8/src/heap/heap.cc
+++ b/deps/v8/src/heap/heap.cc
@@ -302,7 +302,10 @@ Heap::Heap()
"v8::Heap", this, perfetto::ThreadTrack::Current())
.disable_sibling_merge()),
gc_tracing_category_enabled_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
- TRACE_DISABLED_BY_DEFAULT("v8.gc"))) {
+ TRACE_DISABLED_BY_DEFAULT("v8.gc"))),
+ gc_extra_tracing_category_enabled_(
+ TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
+ TRACE_DISABLED_BY_DEFAULT("v8.gc_extra"))) {
#if defined(V8_USE_PERFETTO)
if (perfetto::Tracing::IsInitialized()) {
// Because the track may not get any events of its own it must manually emit
@@ -1309,11 +1312,9 @@ void Heap::CollectAllAvailableGarbage(GarbageCollectionReason gc_reason) {
js_roots += isolate()->global_handles()->handles_count();
js_roots += isolate()->eternal_handles()->handles_count();
size_t cpp_roots = 0;
- if (auto* cpp_heap = CppHeap::From(cpp_heap_)) {
- cpp_roots += cpp_heap->GetStrongPersistentRegion().NodesInUse();
- cpp_roots +=
- cpp_heap->GetStrongCrossThreadPersistentRegion().NodesInUse();
- }
+ auto* cpp_heap = CppHeap::From(cpp_heap_);
+ cpp_roots += cpp_heap->GetStrongPersistentRegion().NodesInUse();
+ cpp_roots += cpp_heap->GetStrongCrossThreadPersistentRegion().NodesInUse();
return js_roots + cpp_roots;
};
@@ -1560,9 +1561,8 @@ void Heap::CollectGarbage(
collector == GarbageCollector::SCAVENGER) {
tracer()->RecordGCPhasesHistograms(record_gc_phases_info.mode());
}
- if ((collector == GarbageCollector::MARK_COMPACTOR ||
- collector == GarbageCollector::MINOR_MARK_SWEEPER) &&
- cpp_heap()) {
+ if (collector == GarbageCollector::MARK_COMPACTOR ||
+ collector == GarbageCollector::MINOR_MARK_SWEEPER) {
CppHeap::From(cpp_heap())->FinishAtomicSweepingIfRunning();
}
}
@@ -1925,8 +1925,7 @@ void Heap::CompleteSweepingFull(CompleteSweepingReason reason) {
EnsureSweepingCompleted(SweepingForcedFinalizationMode::kUnifiedHeap, reason);
DCHECK(!sweeping_in_progress());
- DCHECK_IMPLIES(cpp_heap(),
- !CppHeap::From(cpp_heap())->sweeper().IsSweepingInProgress());
+ DCHECK(!CppHeap::From(cpp_heap())->sweeper().IsSweepingInProgress());
DCHECK(!tracer()->IsSweepingInProgress());
}
@@ -2327,8 +2326,8 @@ void Heap::PerformGarbageCollection(GarbageCollector collector,
// nested GCs.
isolate_->global_handles()->InvokeFirstPassWeakCallbacks();
- if (cpp_heap() && (collector == GarbageCollector::MARK_COMPACTOR ||
- collector == GarbageCollector::MINOR_MARK_SWEEPER)) {
+ if (collector == GarbageCollector::MARK_COMPACTOR ||
+ collector == GarbageCollector::MINOR_MARK_SWEEPER) {
// TraceEpilogue may trigger operations that invalidate global handles. It
// has to be called *after* all other operations that potentially touch
// and reset global handles. It is also still part of the main garbage
@@ -2472,11 +2471,9 @@ void Heap::CompleteSweepingYoung(CompleteSweepingReason reason) {
#if defined(CPPGC_YOUNG_GENERATION)
// Always complete sweeping if young generation is enabled.
- if (cpp_heap()) {
- if (auto* iheap = CppHeap::From(cpp_heap());
- iheap->generational_gc_supported()) {
- iheap->FinishSweepingIfRunning();
- }
+ if (auto* iheap = CppHeap::From(cpp_heap());
+ iheap->generational_gc_supported()) {
+ iheap->FinishSweepingIfRunning();
}
#endif // defined(CPPGC_YOUNG_GENERATION)
}
@@ -5343,7 +5340,7 @@ size_t Heap::YoungGenerationConsumedBytes() const {
}
size_t Heap::EmbedderSizeOfObjects() const {
- return cpp_heap_ ? CppHeap::From(cpp_heap_)->used_size() : 0;
+ return CppHeap::From(cpp_heap_)->used_size();
}
uint64_t Heap::GlobalSizeOfObjects() const {
@@ -5697,8 +5694,7 @@ Heap::IncrementalMarkingLimitReached() {
if (old_generation_space_available > new_space_target_capacity &&
(global_memory_available > new_space_target_capacity)) {
- if (cpp_heap() && gc_count_ == kInitialGCEpoch &&
- limits()->using_initial_limit()) {
+ if (gc_count_ == kInitialGCEpoch && limits()->using_initial_limit()) {
// At this point the embedder memory is above the activation
// threshold. No GC happened so far and it's thus unlikely to get a
// configured heap any time soon. Start a memory reducer in this case
@@ -6250,11 +6246,9 @@ const ::heap::base::Stack& Heap::stack() const {
}
void Heap::StartTearDown() {
- if (cpp_heap_) {
- // This may invoke a GC in case marking is running to get us into a
- // well-defined state for tear down.
- CppHeap::From(cpp_heap_)->StartDetachingIsolate();
- }
+ // This may invoke a GC in case marking is running to get us into a
+ // well-defined state for tear down.
+ CppHeap::From(cpp_heap_)->StartDetachingIsolate();
// Stressing incremental marking should make it likely to force a GC here with
// a CppHeap present. Stress compaction serves as a more deterministic way to
@@ -6326,11 +6320,9 @@ void Heap::TearDown() {
}
}
- if (cpp_heap_) {
- CppHeap::From(cpp_heap_)->DetachIsolate();
- cpp_heap_ = nullptr;
- isolate_->RunReleaseCppHeapCallback(std::move(owning_cpp_heap_));
- }
+ CppHeap::From(cpp_heap_)->DetachIsolate();
+ cpp_heap_ = nullptr;
+ isolate_->RunReleaseCppHeapCallback(std::move(owning_cpp_heap_));
minor_gc_job_.reset();
@@ -7337,7 +7329,7 @@ bool Heap::AllowedToBeMigrated(Tagged<Map> map, Tagged<HeapObject> object,
}
uint64_t Heap::EmbedderAllocationCounter() const {
- return cpp_heap_ ? CppHeap::From(cpp_heap_)->allocated_size() : 0;
+ return CppHeap::From(cpp_heap_)->allocated_size();
}
uint64_t Heap::ExternalAllocationCounter() const {
@@ -7550,11 +7542,9 @@ void Heap::FinishSweepingIfOutOfWork(CompleteSweepingReason reason) {
limits()->UpdateAllocationLimits(CurrentHeapGrowingMode(), bounds);
}
}
- if (cpp_heap()) {
- // Ensure that sweeping is also completed for the C++ managed heap, if one
- // exists and it's out of work.
- CppHeap::From(cpp_heap())->FinishSweepingIfOutOfWork();
- }
+ // Ensure that sweeping is also completed for the C++ managed heap if it's
+ // out of work.
+ CppHeap::From(cpp_heap())->FinishSweepingIfOutOfWork();
}
void Heap::EnsureSweepingCompleted(SweepingForcedFinalizationMode mode,
@@ -7613,16 +7603,14 @@ void Heap::EnsureSweepingCompleted(SweepingForcedFinalizationMode mode,
#endif
}
- if (mode == SweepingForcedFinalizationMode::kUnifiedHeap && cpp_heap()) {
- // Ensure that sweeping is also completed for the C++ managed heap, if one
- // exists.
+ if (mode == SweepingForcedFinalizationMode::kUnifiedHeap) {
+ // Ensure that sweeping is also completed for the C++ managed heap.
CppHeap::From(cpp_heap())->FinishSweepingIfRunning();
DCHECK(!CppHeap::From(cpp_heap())->sweeper().IsSweepingInProgress());
}
- DCHECK_IMPLIES(
- mode == SweepingForcedFinalizationMode::kUnifiedHeap || !cpp_heap(),
- !tracer()->IsSweepingInProgress());
+ DCHECK_IMPLIES(mode == SweepingForcedFinalizationMode::kUnifiedHeap,
+ !tracer()->IsSweepingInProgress());
}
void Heap::EnsureQuarantinedPagesSweepingCompleted() {
diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h
index 810449851fe..39e2304d2a2 100644
--- a/deps/v8/src/heap/heap.h
+++ b/deps/v8/src/heap/heap.h
@@ -291,6 +291,10 @@ class Heap final {
int increment_dispatch_table_allocations() {
return ++dispatch_table_allocations_;
}
+ int dispatch_table_gc_interval() const { return dispatch_table_gc_interval_; }
+ void set_dispatch_table_gc_interval(int interval) {
+ dispatch_table_gc_interval_ = interval;
+ }
#endif
// Emits GC events for DevTools timeline.
@@ -391,6 +395,10 @@ class Heap final {
return *gc_tracing_category_enabled_;
}
+ bool is_gc_extra_tracing_category_enabled() const {
+ return *gc_extra_tracing_category_enabled_;
+ }
+
enum class StackScanMode { kNone, kFull, kSelective };
StackScanMode ConservativeStackScanningModeForMinorGC() const {
if (v8_flags.scavenger_conservative_object_pinning) {
@@ -2390,6 +2398,7 @@ class Heap final {
#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
int dispatch_table_allocations_ = 0;
+ int dispatch_table_gc_interval_ = v8_flags.dispatch_table_gc_interval;
#endif
std::vector<HeapObjectAllocationTracker*> allocation_trackers_;
@@ -2453,6 +2462,7 @@ class Heap final {
std::atomic<uint64_t> total_allocated_bytes_ = 0;
const uint8_t* gc_tracing_category_enabled_ = nullptr;
+ const uint8_t* gc_extra_tracing_category_enabled_ = nullptr;
size_t notify_context_disposed_counter_ = 1;
// Classes in "heap" can be friends.
diff --git a/deps/v8/src/heap/incremental-marking.cc b/deps/v8/src/heap/incremental-marking.cc
index f19e74472d7..a39ccf5ef65 100644
--- a/deps/v8/src/heap/incremental-marking.cc
+++ b/deps/v8/src/heap/incremental-marking.cc
@@ -306,7 +306,7 @@ void IncrementalMarking::StartMarkingMajor() {
isolate()->PrintWithTimestamp("[IncrementalMarking] Running\n");
}
- if (heap()->cpp_heap()) {
+ {
// `StartMarking()` may call back into V8 in corner cases, requiring that
// marking (including write barriers) is fully set up.
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_EMBEDDER_PROLOGUE);
@@ -470,7 +470,7 @@ std::pair<v8::base::TimeDelta, size_t> IncrementalMarking::CppHeapStep(
StepOrigin step_origin) {
DCHECK(IsMarking());
auto* cpp_heap = CppHeap::From(heap_->cpp_heap());
- if (!cpp_heap || !cpp_heap->incremental_marking_supported()) {
+ if (!cpp_heap->incremental_marking_supported()) {
return {};
}
@@ -686,9 +686,7 @@ size_t IncrementalMarking::GetScheduledBytes(StepOrigin step_origin) {
// as the full marker marks both the young and old generations.
size_t estimated_live_bytes = OldGenerationSizeOfObjects();
if (v8_flags.incremental_marking_unified_schedule) {
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap())) {
- estimated_live_bytes += cpp_heap->used_size();
- }
+ estimated_live_bytes += CppHeap::From(heap_->cpp_heap())->used_size();
}
const size_t marked_bytes_limit =
schedule_->GetNextIncrementalStepDuration(estimated_live_bytes);
@@ -763,7 +761,7 @@ bool IncrementalMarking::ShouldFinalize() const {
->mark_compact_collector()
->local_marking_worklists()
->IsEmpty() &&
- (!cpp_heap || cpp_heap->ShouldFinalizeIncrementalMarking());
+ cpp_heap->ShouldFinalizeIncrementalMarking();
}
void IncrementalMarking::FetchBytesMarkedConcurrently() {
@@ -885,24 +883,53 @@ void IncrementalMarking::Step(v8::base::TimeDelta max_duration,
GarbageCollector::MARK_COMPACTOR);
}
- if (V8_UNLIKELY(v8_flags.trace_incremental_marking)) {
+ if (v8_flags.trace_incremental_marking ||
+ heap_->is_gc_extra_tracing_category_enabled()) [[unlikely]] {
const auto v8_max_duration = max_duration - cpp_heap_duration;
const auto v8_marked_bytes_limit =
marked_bytes_limit > cpp_heap_marked_bytes
? marked_bytes_limit - cpp_heap_marked_bytes
: 0;
- isolate()->PrintWithTimestamp(
- "[IncrementalMarking] Step: origin: %s overall: %.1fms "
- "V8: %zuKB (%zuKB), %.1fms (%.1fms), %.1fMB/s "
- "CppHeap: %zuKB (%zuKB), %.1fms (%.1fms)\n",
- ToString(step_origin),
- (v8::base::TimeTicks::Now() - start).InMillisecondsF(), v8_marked_bytes,
- v8_marked_bytes_limit, v8_time.InMillisecondsF(),
- v8_max_duration.InMillisecondsF(),
- heap()->tracer()->IncrementalMarkingSpeedInBytesPerMillisecond() *
- 1000 / MB,
- cpp_heap_marked_bytes, marked_bytes_limit,
- cpp_heap_duration.InMillisecondsF(), max_duration.InMillisecondsF());
+ const auto overall_duration = v8::base::TimeTicks::Now() - start;
+ const double marking_speed_in_bytes_per_ms =
+ heap()->tracer()->IncrementalMarkingSpeedInBytesPerMillisecond();
+
+ if (v8_flags.trace_incremental_marking) [[unlikely]] {
+ isolate()->PrintWithTimestamp(
+ "[IncrementalMarking] Step: origin: %s overall: %.1fms "
+ "V8: %zuKB (%zuKB), %.1fms (%.1fms), %.1fMB/s "
+ "CppHeap: %zuKB (%zuKB), %.1fms (%.1fms)\n",
+ ToString(step_origin), overall_duration.InMillisecondsF(),
+ v8_marked_bytes / KB, v8_marked_bytes_limit / KB,
+ v8_time.InMillisecondsF(), v8_max_duration.InMillisecondsF(),
+ marking_speed_in_bytes_per_ms * 1000 / MB, cpp_heap_marked_bytes / KB,
+ marked_bytes_limit / KB, cpp_heap_duration.InMillisecondsF(),
+ max_duration.InMillisecondsF());
+ }
+
+ if (heap_->is_gc_extra_tracing_category_enabled()) [[unlikely]] {
+ TRACE_EVENT_INSTANT(
+ TRACE_DISABLED_BY_DEFAULT("v8.gc_extra"),
+ "V8.GCIncrementalMarkingStep", "value",
+ [step_origin, overall_duration, v8_marked_bytes,
+ v8_marked_bytes_limit, v8_time, v8_max_duration,
+ marking_speed_in_bytes_per_ms, cpp_heap_marked_bytes,
+ marked_bytes_limit, cpp_heap_duration,
+ max_duration](perfetto::TracedValue ctx) {
+ auto dict = std::move(ctx).WriteDictionary();
+ dict.Add("origin", ToString(step_origin));
+ dict.Add("overall_duration", overall_duration.InMillisecondsF());
+ dict.Add("marking_speed", marking_speed_in_bytes_per_ms);
+ dict.Add("v8_marked_bytes", v8_marked_bytes);
+ dict.Add("v8_marked_bytes_limit", v8_marked_bytes_limit);
+ dict.Add("v8_duration", v8_time.InMillisecondsF());
+ dict.Add("v8_max_duration", v8_max_duration.InMillisecondsF());
+ dict.Add("cpp_heap_marked_bytes", cpp_heap_marked_bytes);
+ dict.Add("cpp_heap_marked_bytes_limit", marked_bytes_limit);
+ dict.Add("cpp_heap_duration", cpp_heap_duration.InMillisecondsF());
+ dict.Add("cpp_heap_max_duration", max_duration.InMillisecondsF());
+ });
+ }
}
}
diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc
index caa1192d2fc..6712456d29a 100644
--- a/deps/v8/src/heap/mark-compact.cc
+++ b/deps/v8/src/heap/mark-compact.cc
@@ -425,9 +425,7 @@ base::EnumSet<CodeFlushMode> GetCodeFlushMode(Isolate* isolate) {
code_flush_mode.Add(CodeFlushMode::kForceFlush);
}
- if (isolate->heap()->IsLastResortGC() &&
- (v8_flags.flush_code_based_on_time ||
- v8_flags.flush_code_based_on_tab_visibility)) {
+ if (isolate->heap()->IsLastResortGC()) {
code_flush_mode.Add(CodeFlushMode::kForceFlush);
}
@@ -464,9 +462,10 @@ void MarkCompactCollector::StartMarking(
// CppHeap's marker must be initialized before the V8 marker to allow
// exchanging of worklists.
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap())) {
+ {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_EMBEDDER_PROLOGUE);
- cpp_heap->InitializeMarking(CppHeap::CollectionType::kMajor, schedule);
+ CppHeap::From(heap_->cpp_heap())
+ ->InitializeMarking(CppHeap::CollectionType::kMajor, schedule);
}
std::vector<Address> contexts =
@@ -481,11 +480,9 @@ void MarkCompactCollector::StartMarking(
heap_->tracer()->NotifyMarkingStart();
code_flush_mode_ = GetCodeFlushMode(heap_->isolate());
marking_worklists_.CreateContextWorklists(contexts);
- auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
local_marking_worklists_ = std::make_unique<MarkingWorklists::Local>(
&marking_worklists_,
- cpp_heap ? cpp_heap->CreateCppMarkingStateForMutatorThread()
- : MarkingWorklists::Local::kNoCppMarkingState);
+ CppHeap::From(heap_->cpp_heap_)->CreateCppMarkingStateForMutatorThread());
local_weak_objects_ = std::make_unique<WeakObjects::Local>(weak_objects());
marking_visitor_ = std::make_unique<MainMarkingVisitor>(
local_marking_worklists_.get(), local_weak_objects_.get(), heap_, epoch(),
@@ -521,9 +518,7 @@ void MarkCompactCollector::MaybeEnableBackgroundThreadsInCycle(
heap_->concurrent_marking()->RescheduleJobIfNeeded(
GarbageCollector::MARK_COMPACTOR);
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->ReEnableConcurrentMarking();
- }
+ CppHeap::From(heap_->cpp_heap_)->ReEnableConcurrentMarking();
}
}
}
@@ -537,9 +532,7 @@ void MarkCompactCollector::CollectGarbage() {
MarkLiveObjects();
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->ProcessCrossThreadWeakness();
- }
+ CppHeap::From(heap_->cpp_heap_)->ProcessCrossThreadWeakness();
// This will walk dead object graphs and so requires that all references are
// still intact.
@@ -547,9 +540,7 @@ void MarkCompactCollector::CollectGarbage() {
ClearNonLiveReferences();
VerifyMarking();
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->FinishMarkingAndProcessWeakness();
- }
+ CppHeap::From(heap_->cpp_heap_)->FinishMarkingAndProcessWeakness();
heap_->memory_measurement()->FinishProcessing(native_context_stats_);
@@ -819,7 +810,7 @@ void MarkCompactCollector::Prepare() {
if (!heap_->incremental_marking()->IsMarking()) {
StartCompaction(StartCompactionMode::kAtomic);
StartMarking();
- if (heap_->cpp_heap_) {
+ {
TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_MARK_EMBEDDER_PROLOGUE);
// `StartMarking()` immediately starts marking which requires V8 worklists
// to be set up.
@@ -841,9 +832,7 @@ void MarkCompactCollector::FinishConcurrentMarking() {
heap_->concurrent_marking()->FlushMemoryChunkData();
heap_->concurrent_marking()->FlushNativeContexts(&native_context_stats_);
}
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->FinishConcurrentMarkingIfNeeded();
- }
+ CppHeap::From(heap_->cpp_heap_)->FinishConcurrentMarkingIfNeeded();
}
void MarkCompactCollector::VerifyMarking() {
@@ -2295,12 +2284,10 @@ void MarkCompactCollector::MarkTransitiveClosureLinear() {
}
void MarkCompactCollector::ProcessCppHeapWorklist() {
- auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
- if (!cpp_heap) return;
-
TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_MARK_EMBEDDER_TRACING);
- cpp_heap->AdvanceMarking(v8::base::TimeDelta::Max(), SIZE_MAX,
- StackState::kMayContainHeapPointers);
+ CppHeap::From(heap_->cpp_heap_)
+ ->AdvanceMarking(v8::base::TimeDelta::Max(), SIZE_MAX,
+ StackState::kMayContainHeapPointers);
}
namespace {
@@ -2600,10 +2587,8 @@ void MarkCompactCollector::MarkLiveObjects() {
state_ = MARK_LIVE_OBJECTS;
#endif
- if (heap_->cpp_heap_) {
- CppHeap::From(heap_->cpp_heap_)
- ->EnterFinalPause(heap_->embedder_stack_state_);
- }
+ CppHeap::From(heap_->cpp_heap_)
+ ->EnterFinalPause(heap_->embedder_stack_state_);
RootMarkingVisitor root_visitor(this);
@@ -2639,11 +2624,9 @@ void MarkCompactCollector::MarkLiveObjects() {
// Complete the transitive closure single-threaded to avoid races with
// multiple threads when processing weak maps and embedder heaps.
CHECK(heap_->concurrent_marking()->IsStopped());
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap())) {
- // Lock the process-global mutex here and mark cross-thread roots again.
- // This is done as late as possible to keep locking durations short.
- cpp_heap->EnterProcessGlobalAtomicPause();
- }
+ // Lock the process-global mutex here and mark cross-thread roots again.
+ // This is done as late as possible to keep locking durations short.
+ CppHeap::From(heap_->cpp_heap())->EnterProcessGlobalAtomicPause();
if (!MarkTransitiveClosureFixpoint()) {
MarkTransitiveClosureLinear();
}
diff --git a/deps/v8/src/heap/mark-sweep-utilities.cc b/deps/v8/src/heap/mark-sweep-utilities.cc
index afb2ba9125f..20974333f6d 100644
--- a/deps/v8/src/heap/mark-sweep-utilities.cc
+++ b/deps/v8/src/heap/mark-sweep-utilities.cc
@@ -140,8 +140,6 @@ void StringForwardingTableCleanerBase::DisposeExternalResource(
bool IsCppHeapMarkingFinished(
Heap* heap, MarkingWorklists::Local* local_marking_worklists) {
const auto* cpp_heap = CppHeap::From(heap->cpp_heap());
- if (!cpp_heap) return true;
-
return cpp_heap->IsMarkingDone() && local_marking_worklists->IsWrapperEmpty();
}
diff --git a/deps/v8/src/heap/marking-visitor-inl.h b/deps/v8/src/heap/marking-visitor-inl.h
index 39b5b653247..79473b3945a 100644
--- a/deps/v8/src/heap/marking-visitor-inl.h
+++ b/deps/v8/src/heap/marking-visitor-inl.h
@@ -557,47 +557,30 @@ bool MarkingVisitorBase<ConcreteVisitor>::ShouldFlushCode(
template <typename ConcreteVisitor>
bool MarkingVisitorBase<ConcreteVisitor>::IsOld(
Tagged<SharedFunctionInfo> sfi) const {
- if (v8_flags.flush_code_based_on_time) {
- return sfi->age() >= v8_flags.bytecode_old_time;
- } else if (v8_flags.flush_code_based_on_tab_visibility) {
- return isolate_in_background_ ||
- V8_UNLIKELY(sfi->age() == SharedFunctionInfo::kMaxAge);
- } else {
- return sfi->age() >= v8_flags.bytecode_old_age;
- }
+ return sfi->age() >= v8_flags.bytecode_old_time;
}
template <typename ConcreteVisitor>
void MarkingVisitorBase<ConcreteVisitor>::MakeOlder(
Tagged<SharedFunctionInfo> sfi) const {
- if (v8_flags.flush_code_based_on_time) {
- if (code_flushing_increase_ == 0) {
- return;
- }
-
- uint16_t current_age;
- uint16_t updated_age;
- do {
- current_age = sfi->age();
- // When the age is 0, it was reset by the function prologue in
- // Ignition/Sparkplug. But that might have been some time after the last
- // full GC. So in this case we don't increment the value like we normally
- // would but just set the age to 1. All non-0 values can be incremented as
- // expected (we add the number of seconds since the last GC) as they were
- // definitely last executed before the last full GC.
- updated_age = current_age == 0
- ? 1
- : SaturateAdd(current_age, code_flushing_increase_);
- } while (sfi->CompareExchangeAge(current_age, updated_age) != current_age);
- } else if (v8_flags.flush_code_based_on_tab_visibility) {
- // No need to increment age.
- } else {
- uint16_t age = sfi->age();
- if (age < v8_flags.bytecode_old_age) {
- sfi->CompareExchangeAge(age, age + 1);
- }
- DCHECK_LE(sfi->age(), v8_flags.bytecode_old_age);
+ if (code_flushing_increase_ == 0) {
+ return;
}
+
+ uint16_t current_age;
+ uint16_t updated_age;
+ do {
+ current_age = sfi->age();
+ // When the age is 0, it was reset by the function prologue in
+ // Ignition/Sparkplug. But that might have been some time after the last
+ // full GC. So in this case we don't increment the value like we normally
+ // would but just set the age to 1. All non-0 values can be incremented as
+ // expected (we add the number of seconds since the last GC) as they were
+ // definitely last executed before the last full GC.
+ updated_age = current_age == 0
+ ? 1
+ : SaturateAdd(current_age, code_flushing_increase_);
+ } while (sfi->CompareExchangeAge(current_age, updated_age) != current_age);
}
template <typename ConcreteVisitor>
diff --git a/deps/v8/src/heap/marking-visitor.h b/deps/v8/src/heap/marking-visitor.h
index 76936d3469c..ece93424e84 100644
--- a/deps/v8/src/heap/marking-visitor.h
+++ b/deps/v8/src/heap/marking-visitor.h
@@ -60,8 +60,7 @@ class MarkingVisitorBase : public ConcurrentHeapVisitor<ConcreteVisitor> {
mark_compact_epoch_(mark_compact_epoch),
code_flush_mode_(code_flush_mode),
should_keep_ages_unchanged_(should_keep_ages_unchanged),
- code_flushing_increase_(code_flushing_increase),
- isolate_in_background_(heap->isolate()->is_backgrounded())
+ code_flushing_increase_(code_flushing_increase)
#ifdef V8_COMPRESS_POINTERS
,
external_pointer_table_(&heap->isolate()->external_pointer_table()),
@@ -233,7 +232,6 @@ class MarkingVisitorBase : public ConcurrentHeapVisitor<ConcreteVisitor> {
const base::EnumSet<CodeFlushMode> code_flush_mode_;
const bool should_keep_ages_unchanged_;
const uint16_t code_flushing_increase_;
- const bool isolate_in_background_;
#ifdef V8_COMPRESS_POINTERS
ExternalPointerTable* const external_pointer_table_;
ExternalPointerTable* const shared_external_pointer_table_;
diff --git a/deps/v8/src/heap/memory-measurement.cc b/deps/v8/src/heap/memory-measurement.cc
index 736fd989e68..f110e01cc1a 100644
--- a/deps/v8/src/heap/memory-measurement.cc
+++ b/deps/v8/src/heap/memory-measurement.cc
@@ -387,17 +387,19 @@ void NativeContextStats::IncrementExternalSize(Address context, Tagged<Map> map,
size_t external_size = 0;
if (instance_type == JS_ARRAY_BUFFER_TYPE) {
auto js_array_buffer = Cast<JSArrayBuffer>(object);
- if (js_array_buffer->is_resizable_by_js() &&
- !js_array_buffer->is_shared()) {
- // Reading the JS-visible byte length of a RAB during concurrent marking
- // could cause a data race, because the main thread can update it
- // concurrently. Instead, we use the atomically updated accounting length
- // from the extension, which is the correct metric for GC memory
- // measurement.
+ if (!js_array_buffer->is_shared()) {
+ // Reading the JS-visible byte length of a non-shared ArrayBuffer during
+ // concurrent marking can cause a data race because the main thread may
+ // update it concurrently (e.g. when materializing an on-heap TypedArray's
+ // buffer, detaching, or resizing a RAB). Instead, we use the atomically
+ // updated accounting length from the extension.
if (auto ext = js_array_buffer->extension()) {
+ ext->InitializationBarrier();
external_size = ext->accounting_length();
}
} else {
+ // For SharedArrayBuffers, accounting_length() is always 0 (see
+ // BackingStore::PerIsolateAccountingLength()), so use GetByteLength().
external_size = js_array_buffer->GetByteLength();
}
} else {
diff --git a/deps/v8/src/heap/minor-mark-sweep.cc b/deps/v8/src/heap/minor-mark-sweep.cc
index ea2805d9edf..fff48f019c6 100644
--- a/deps/v8/src/heap/minor-mark-sweep.cc
+++ b/deps/v8/src/heap/minor-mark-sweep.cc
@@ -296,13 +296,11 @@ MinorMarkSweepCollector::MinorMarkSweepCollector(Heap* heap)
sweeper_(heap_->sweeper()) {}
void MinorMarkSweepCollector::PerformWrapperTracing() {
- auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
- if (!cpp_heap) return;
-
TRACE_GC(heap_->tracer(), GCTracer::Scope::MINOR_MS_MARK_EMBEDDER_TRACING);
local_marking_worklists()->PublishCppHeapObjects();
- cpp_heap->AdvanceMarking(v8::base::TimeDelta::Max(), SIZE_MAX,
- StackState::kMayContainHeapPointers);
+ CppHeap::From(heap_->cpp_heap_)
+ ->AdvanceMarking(v8::base::TimeDelta::Max(), SIZE_MAX,
+ StackState::kMayContainHeapPointers);
}
MinorMarkSweepCollector::~MinorMarkSweepCollector() = default;
@@ -330,9 +328,7 @@ void MinorMarkSweepCollector::FinishConcurrentMarking() {
CHECK(heap_->concurrent_marking()->IsStopped());
heap_->tracer()->SampleConcurrencyEsimate(
heap_->concurrent_marking()->FetchAndResetConcurrencyEstimate());
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->FinishConcurrentMarkingIfNeeded();
- }
+ CppHeap::From(heap_->cpp_heap_)->FinishConcurrentMarkingIfNeeded();
}
#ifdef DEBUG
@@ -371,7 +367,7 @@ void MinorMarkSweepCollector::StartMarking(bool force_use_background_threads) {
auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
// CppHeap's marker must be initialized before the V8 marker to allow
// exchanging of worklists.
- if (cpp_heap && cpp_heap->generational_gc_supported()) {
+ if (cpp_heap->generational_gc_supported()) {
TRACE_GC(heap_->tracer(), GCTracer::Scope::MINOR_MS_MARK_EMBEDDER_PROLOGUE);
cpp_heap->InitializeMarking(CppHeap::CollectionType::kMinor);
}
@@ -432,9 +428,7 @@ void MinorMarkSweepCollector::CollectGarbage() {
is_in_atomic_pause_.store(true, std::memory_order_relaxed);
MarkLiveObjects();
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->ProcessCrossThreadWeakness();
- }
+ CppHeap::From(heap_->cpp_heap_)->ProcessCrossThreadWeakness();
ClearNonLiveReferences();
#ifdef VERIFY_HEAP
if (v8_flags.verify_heap) {
@@ -444,9 +438,7 @@ void MinorMarkSweepCollector::CollectGarbage() {
}
#endif // VERIFY_HEAP
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_)) {
- cpp_heap->FinishMarkingAndProcessWeakness();
- }
+ CppHeap::From(heap_->cpp_heap_)->FinishMarkingAndProcessWeakness();
Sweep();
Finish();
@@ -526,8 +518,7 @@ void MinorMarkSweepCollector::ClearNonLiveReferences() {
GCTracer::Scope::MINOR_MS_CLEAR_WEAK_GLOBAL_HANDLES);
isolate->global_handles()->ProcessWeakYoungObjects(
nullptr, &IsUnmarkedObjectInYoungGeneration);
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
- cpp_heap && cpp_heap->generational_gc_supported()) {
+ if (CppHeap::From(heap_->cpp_heap_)->generational_gc_supported()) {
isolate->traced_handles()->ResetYoungDeadNodes(
&IsUnmarkedObjectInYoungGeneration);
} else {
@@ -614,8 +605,8 @@ void VisitObjectWithCppHeapPointerField(
void MinorMarkSweepCollector::MarkRootsFromTracedHandles(
YoungGenerationRootMarkingVisitor& root_visitor) {
TRACE_GC(heap_->tracer(), GCTracer::Scope::MINOR_MS_MARK_TRACED_HANDLES);
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
- cpp_heap && cpp_heap->generational_gc_supported()) {
+ auto* cpp_heap = CppHeap::From(heap_->cpp_heap_);
+ if (cpp_heap->generational_gc_supported()) {
// Visit the Oilpan-to-V8 remembered set.
heap_->isolate()->traced_handles()->IterateAndMarkYoungRootsWithOldHosts(
&root_visitor);
@@ -723,9 +714,8 @@ void MinorMarkSweepCollector::MarkLiveObjects() {
MarkRoots(root_visitor, was_marked_incrementally);
// CppGC starts parallel marking tasks that will trace TracedReferences.
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap())) {
- cpp_heap->EnterFinalPause(heap_->embedder_stack_state_);
- }
+ CppHeap::From(heap_->cpp_heap())
+ ->EnterFinalPause(heap_->embedder_stack_state_);
{
// Mark the transitive closure in parallel.
@@ -748,9 +738,7 @@ void MinorMarkSweepCollector::MarkLiveObjects() {
{
TRACE_GC(heap_->tracer(), GCTracer::Scope::MINOR_MS_MARK_CLOSURE);
- if (auto* cpp_heap = CppHeap::From(heap_->cpp_heap())) {
- cpp_heap->EnterProcessGlobalAtomicPause();
- }
+ CppHeap::From(heap_->cpp_heap())->EnterProcessGlobalAtomicPause();
DrainMarkingWorklist();
}
CHECK(local_marking_worklists()->IsEmpty());
diff --git a/deps/v8/src/heap/setup-heap-internal.cc b/deps/v8/src/heap/setup-heap-internal.cc
index 4448bd8400e..7a4e5c3e0bf 100644
--- a/deps/v8/src/heap/setup-heap-internal.cc
+++ b/deps/v8/src/heap/setup-heap-internal.cc
@@ -1414,6 +1414,12 @@ bool Heap::CreateReadOnlyObjects() {
set_property_cell_hole_value(UncheckedCast<PropertyCellHole>(make_hole()));
set_hash_table_hole_value(UncheckedCast<HashTableHole>(make_hole()));
set_promise_hole_value(UncheckedCast<PromiseHole>(make_hole()));
+#ifdef V8_ENABLE_TDZ_HOLE
+ set_tdz_hole_value(UncheckedCast<TdzHole>(make_hole()));
+#else
+ // TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+ set_disabled_tdz_hole_value(UncheckedCast<DisabledTdzHole>(make_hole()));
+#endif
set_uninitialized_value(UncheckedCast<UninitializedHole>(make_hole()));
set_arguments_marker(UncheckedCast<ArgumentsMarker>(make_hole()));
set_termination_exception(UncheckedCast<TerminationException>(make_hole()));
diff --git a/deps/v8/src/heap/young-generation-marking-visitor-inl.h b/deps/v8/src/heap/young-generation-marking-visitor-inl.h
index 14c6c693722..3f13c77d3f8 100644
--- a/deps/v8/src/heap/young-generation-marking-visitor-inl.h
+++ b/deps/v8/src/heap/young-generation-marking-visitor-inl.h
@@ -30,9 +30,7 @@ YoungGenerationMarkingVisitor<marking_mode>::YoungGenerationMarkingVisitor(
isolate_(heap->isolate()),
marking_worklists_local_(
heap->minor_mark_sweep_collector()->marking_worklists(),
- heap->cpp_heap()
- ? CppHeap::From(heap->cpp_heap())->CreateCppMarkingState()
- : MarkingWorklists::Local::kNoCppMarkingState),
+ CppHeap::From(heap->cpp_heap())->CreateCppMarkingState()),
ephemeron_table_list_local_(
*heap->minor_mark_sweep_collector()->ephemeron_table_list()),
pretenuring_handler_(heap->pretenuring_handler()),
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc
index c5f4df6edfb..c262e24e75f 100644
--- a/deps/v8/src/ic/accessor-assembler.cc
+++ b/deps/v8/src/ic/accessor-assembler.cc
@@ -1153,7 +1153,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
// The handler is only installed for exports that exist.
TNode<Object> value = LoadCellValue(cell);
Label is_the_hole(this, Label::kDeferred);
- GotoIf(IsTheHole(value), &is_the_hole);
+ GotoIf(IsTdzHole(value), &is_the_hole);
exit_point->Return(value);
BIND(&is_the_hole);
@@ -3937,7 +3937,7 @@ void AccessorAssembler::ScriptContextTableLookup(
TNode<IntPtrT> var_index = IntPtrAdd(
IntPtrConstant(Context::MIN_CONTEXT_SLOTS), context_local_index);
TNode<Object> result = LoadContextElement(script_context, var_index);
- GotoIf(IsTheHole(result), found_hole);
+ GotoIf(IsTdzHole(result), found_hole);
Return(result);
}
}
diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc
index ad7852b0ba3..7ae7d8f99d0 100644
--- a/deps/v8/src/ic/ic.cc
+++ b/deps/v8/src/ic/ic.cc
@@ -504,7 +504,7 @@ MaybeDirectHandle<Object> LoadGlobalIC::Load(Handle<Name> name,
if (script_contexts->Lookup(str_name, &lookup_result)) {
DirectHandle<Context> script_context(
script_contexts->get(lookup_result.context_index), isolate());
- if (script_context->IsElementTheHole(lookup_result.slot_index)) {
+ if (script_context->IsElementTdzHole(lookup_result.slot_index)) {
// Do not install stubs and stay pre-monomorphic for
// uninitialized accesses.
THROW_NEW_ERROR(
@@ -2157,7 +2157,7 @@ MaybeDirectHandle<Object> StoreGlobalIC::Store(Handle<Name> name,
return TypeError(MessageTemplate::kConstAssign, global, name);
}
- if (script_context->IsElementTheHole(lookup_result.slot_index)) {
+ if (script_context->IsElementTdzHole(lookup_result.slot_index)) {
// Do not install stubs and stay pre-monomorphic for uninitialized
// accesses.
AllowGarbageCollection yes_gc;
@@ -3627,7 +3627,7 @@ RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) {
{
DisallowGarbageCollection no_gc;
- if (script_context->IsElementTheHole(lookup_result.slot_index)) {
+ if (script_context->IsElementTdzHole(lookup_result.slot_index)) {
AllowGarbageCollection yes_gc;
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
diff --git a/deps/v8/src/inspector/BUILD.gn b/deps/v8/src/inspector/BUILD.gn
index 8f38ff9342c..e9e28ae55ac 100644
--- a/deps/v8/src/inspector/BUILD.gn
+++ b/deps/v8/src/inspector/BUILD.gn
@@ -60,9 +60,10 @@ inspector_protocol_generate("protocol_generated_sources") {
}
config("inspector_config") {
- # Only targets in this file and v8_internal_headers can depend on this.
visibility = [
":*",
+ "../..:v8",
+ "../..:v8_headers",
"../..:v8_internal_headers",
]
include_dirs = [ "$target_gen_dir/../../include" ]
@@ -75,12 +76,34 @@ config("inspector_internal_config") {
include_dirs = [ "../../include" ]
}
+v8_header_set("inspector_headers") {
+ configs = [ ":inspector_internal_config" ]
+ public_configs = [ ":inspector_config" ]
+
+ public_deps = [
+ ":protocol_generated_sources",
+ "../..:cppgc_headers",
+ "../..:v8_headers",
+ ]
+
+ sources = [
+ "$target_gen_dir/../../include/inspector/Debugger.h",
+ "$target_gen_dir/../../include/inspector/Runtime.h",
+ "$target_gen_dir/../../include/inspector/Schema.h",
+ "../../include/v8-inspector-protocol.h",
+ "../../include/v8-inspector.h",
+ ]
+}
+
v8_header_set("inspector_test_headers") {
configs = [ ":inspector_internal_config" ]
public_deps = [ "../..:v8_headers" ]
- sources = [ "test-interface.h" ]
+ sources = [
+ "../../src/sandbox/cppheap-pointer-tag.h",
+ "test-interface.h",
+ ]
}
v8_source_set("inspector_string_conversions") {
@@ -101,6 +124,7 @@ v8_source_set("inspector") {
]
public_deps = [
+ ":inspector_headers",
":inspector_test_headers",
":protocol_generated_sources",
"../../:v8_libbase",
@@ -111,10 +135,6 @@ v8_source_set("inspector") {
public_configs = [ ":inspector_config" ]
sources = rebase_path(_protocol_generated, ".", target_gen_dir)
- sources += [
- "../../include/v8-inspector-protocol.h",
- "../../include/v8-inspector.h",
- ]
sources += [
"crc32.cc",
"crc32.h",
diff --git a/deps/v8/src/inspector/DEPS b/deps/v8/src/inspector/DEPS
index b29d772d1b4..c653df7881b 100644
--- a/deps/v8/src/inspector/DEPS
+++ b/deps/v8/src/inspector/DEPS
@@ -17,6 +17,7 @@ include_rules = [
"+src/tracing",
"+src/debug/debug-interface.h",
"+src/debug/interface-types.h",
+ "+src/sandbox/cppheap-pointer-tag.h",
"+src/base/vector.h",
"+src/base/enum-set.h",
"+src/utils/sha-256.h",
diff --git a/deps/v8/src/inspector/custom-preview.cc b/deps/v8/src/inspector/custom-preview.cc
index 469705c11f1..b9133b24b5f 100644
--- a/deps/v8/src/inspector/custom-preview.cc
+++ b/deps/v8/src/inspector/custom-preview.cc
@@ -56,7 +56,128 @@ void reportError(v8::Local<v8::Context> context, const v8::TryCatch& tryCatch,
bool substituteObjectTags(int sessionId, const String16& groupName,
v8::Local<v8::Context> context,
- v8::Local<v8::Array> jsonML, int maxDepth) {
+ v8::Local<v8::Array> jsonML, int maxDepth,
+ std::unique_ptr<protocol::ListValue>* result);
+
+bool jsonMLValueToProtocolValue(int sessionId, const String16& groupName,
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Value> value, int maxDepth,
+ std::unique_ptr<protocol::Value>* result) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::TryCatch tryCatch(isolate);
+
+ if (value->IsProxy()) {
+ reportError(context, tryCatch, "Proxy values are not allowed in JSONML");
+ return false;
+ }
+ if (value->IsNull() || value->IsUndefined() || value->IsFunction() ||
+ value->IsSymbol()) {
+ *result = protocol::Value::null();
+ return true;
+ }
+ if (value->IsBoolean()) {
+ *result =
+ protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
+ return true;
+ }
+ if (value->IsNumber()) {
+ double doubleValue = value.As<v8::Number>()->Value();
+ if (doubleValue == 0.0) {
+ *result = protocol::FundamentalValue::create(0);
+ return true;
+ }
+ if (!std::isfinite(doubleValue)) {
+ *result = protocol::Value::null();
+ return true;
+ }
+ if (doubleValue >= std::numeric_limits<int>::min() &&
+ doubleValue <= std::numeric_limits<int>::max()) {
+ int intValue = static_cast<int>(doubleValue);
+ if (intValue == doubleValue) {
+ *result = protocol::FundamentalValue::create(intValue);
+ return true;
+ }
+ }
+ *result = protocol::FundamentalValue::create(doubleValue);
+ return true;
+ }
+ if (value->IsString()) {
+ *result = protocol::StringValue::create(
+ toProtocolString(isolate, value.As<v8::String>()));
+ return true;
+ }
+ if (value->IsArray()) {
+ std::unique_ptr<protocol::ListValue> listResult;
+ if (!substituteObjectTags(sessionId, groupName, context,
+ value.As<v8::Array>(), maxDepth, &listResult)) {
+ return false;
+ }
+ *result = std::move(listResult);
+ return true;
+ }
+ if (value->IsObject()) {
+ if (maxDepth <= 0) {
+ reportError(context, tryCatch,
+ "Too deep hierarchy of inlined custom previews");
+ return false;
+ }
+ v8::Local<v8::Object> object = value.As<v8::Object>();
+ auto dict = protocol::DictionaryValue::create();
+ v8::Local<v8::Array> propertyNames;
+ if (!object->GetOwnPropertyNames(context).ToLocal(&propertyNames)) {
+ reportError(context, tryCatch);
+ return false;
+ }
+ uint32_t length = propertyNames->Length();
+ for (uint32_t i = 0; i < length; ++i) {
+ v8::Local<v8::Value> name;
+ if (!propertyNames->Get(context, i).ToLocal(&name)) {
+ reportError(context, tryCatch);
+ return false;
+ }
+ if (name->IsString()) {
+ v8::Maybe<bool> hasRealNamedProperty =
+ object->HasRealNamedProperty(context, name.As<v8::String>());
+ if (hasRealNamedProperty.IsNothing()) {
+ reportError(context, tryCatch);
+ return false;
+ }
+ if (!hasRealNamedProperty.FromJust()) continue;
+ }
+ v8::Local<v8::String> propertyName;
+ if (!name->ToString(context).ToLocal(&propertyName)) {
+ reportError(context, tryCatch);
+ return false;
+ }
+ v8::Local<v8::Value> property;
+ if (!object->Get(context, name).ToLocal(&property)) {
+ reportError(context, tryCatch);
+ return false;
+ }
+ if (property->IsUndefined() || property->IsFunction() ||
+ property->IsSymbol()) {
+ continue;
+ }
+ std::unique_ptr<protocol::Value> protocolProperty;
+ if (!jsonMLValueToProtocolValue(sessionId, groupName, context, property,
+ maxDepth - 1, &protocolProperty)) {
+ return false;
+ }
+ dict->setValue(toProtocolString(isolate, propertyName),
+ std::move(protocolProperty));
+ }
+ *result = std::move(dict);
+ return true;
+ }
+ reportError(context, tryCatch, "Cannot serialize value in JSONML");
+ return false;
+}
+
+bool substituteObjectTags(int sessionId, const String16& groupName,
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Array> jsonML, int maxDepth,
+ std::unique_ptr<protocol::ListValue>* result) {
+ *result = protocol::ListValue::create();
if (!jsonML->Length()) return true;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::TryCatch tryCatch(isolate);
@@ -72,9 +193,20 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
reportError(context, tryCatch);
return false;
}
+ if (firstValue->IsProxy()) {
+ reportError(context, tryCatch, "Proxy values are not allowed in JSONML");
+ return false;
+ }
+ if (!firstValue->IsString()) {
+ reportError(context, tryCatch, "tag name must be a string");
+ return false;
+ }
v8::Local<v8::String> objectLiteral = toV8String(isolate, "object");
- if (jsonML->Length() == 2 && firstValue->IsString() &&
- firstValue.As<v8::String>()->StringEquals(objectLiteral)) {
+ if (firstValue.As<v8::String>()->StringEquals(objectLiteral)) {
+ if (jsonML->Length() != 2) {
+ reportError(context, tryCatch, "object tag should have 2 elements");
+ return false;
+ }
v8::Local<v8::Value> attributesValue;
if (!jsonML->Get(context, 1).ToLocal(&attributesValue)) {
reportError(context, tryCatch);
@@ -129,22 +261,19 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
reportError(context, tryCatch, "cannot wrap value");
return false;
}
- std::vector<uint8_t> json;
- v8_crdtp::json::ConvertCBORToJSON(v8_crdtp::SpanFrom(wrapper->Serialize()),
- &json);
- v8::Local<v8::Value> jsonWrapper;
- v8_inspector::StringView serialized(json.data(), json.size());
- if (!v8::JSON::Parse(context, toV8String(isolate, serialized))
- .ToLocal(&jsonWrapper)) {
+ std::vector<uint8_t> cbor = wrapper->Serialize();
+ std::unique_ptr<protocol::Value> protocolWrapper =
+ protocol::Value::parseBinary(cbor.data(), cbor.size());
+ if (!protocolWrapper) {
reportError(context, tryCatch, "cannot wrap value");
return false;
}
- if (jsonML->Set(context, 1, jsonWrapper).IsNothing()) {
- reportError(context, tryCatch);
- return false;
- }
+ (*result)->pushValue(protocol::StringValue::create("object"));
+ (*result)->pushValue(std::move(protocolWrapper));
} else {
- for (uint32_t i = 0; i < jsonML->Length(); ++i) {
+ (*result)->pushValue(protocol::StringValue::create(
+ toProtocolString(isolate, firstValue.As<v8::String>())));
+ for (uint32_t i = 1; i < jsonML->Length(); ++i) {
v8::Local<v8::Value> value;
if (!jsonML->Get(context, i).ToLocal(&value)) {
reportError(context, tryCatch);
@@ -155,10 +284,25 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
"Proxy values are not allowed in JSONML");
return false;
}
- if (value->IsArray() && value.As<v8::Array>()->Length() > 0 &&
- !substituteObjectTags(sessionId, groupName, context,
- value.As<v8::Array>(), maxDepth - 1)) {
- return false;
+ if (value->IsArray()) {
+ std::unique_ptr<protocol::ListValue> childList;
+ if (value.As<v8::Array>()->Length() > 0) {
+ if (!substituteObjectTags(sessionId, groupName, context,
+ value.As<v8::Array>(), maxDepth - 1,
+ &childList)) {
+ return false;
+ }
+ } else {
+ childList = protocol::ListValue::create();
+ }
+ (*result)->pushValue(std::move(childList));
+ } else {
+ std::unique_ptr<protocol::Value> protocolElement;
+ if (!jsonMLValueToProtocolValue(sessionId, groupName, context, value,
+ maxDepth - 1, &protocolElement)) {
+ return false;
+ }
+ (*result)->pushValue(std::move(protocolElement));
}
}
}
@@ -169,7 +313,10 @@ void bodyCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::TryCatch tryCatch(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
- v8::Local<v8::Object> bodyConfig = info.Data().As<v8::Object>();
+ v8::MicrotasksScope microtasksScope(context,
+ v8::MicrotasksScope::kDoNotRunMicrotasks);
+ v8::Local<v8::Object> bodyConfig =
+ info.DataV2().As<v8::Value>().As<v8::Object>();
v8::Local<v8::Value> objectValue;
if (!bodyConfig->Get(context, toV8String(isolate, "object"))
@@ -252,14 +399,24 @@ void bodyCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
return;
}
v8::Local<v8::Array> jsonML = formattedValue.As<v8::Array>();
- if (jsonML->Length() &&
- !substituteObjectTags(
+ std::unique_ptr<protocol::ListValue> protocolJsonML;
+ if (!substituteObjectTags(
sessionIdValue.As<v8::Int32>()->Value(),
toProtocolString(isolate, groupNameValue.As<v8::String>()), context,
- jsonML, kMaxCustomPreviewDepth)) {
+ jsonML, kMaxCustomPreviewDepth, &protocolJsonML)) {
return;
}
- info.GetReturnValue().Set(jsonML);
+ std::vector<uint8_t> json;
+ v8_crdtp::json::ConvertCBORToJSON(
+ v8_crdtp::SpanFrom(protocolJsonML->Serialize()), &json);
+ v8::Local<v8::Value> detachedJsonML;
+ v8_inspector::StringView serialized(json.data(), json.size());
+ if (!v8::JSON::Parse(context, toV8String(isolate, serialized))
+ .ToLocal(&detachedJsonML)) {
+ reportError(context, tryCatch, "cannot serialize body");
+ return;
+ }
+ info.GetReturnValue().Set(detachedJsonML);
}
} // anonymous namespace
@@ -341,16 +498,17 @@ void generateCustomPreview(v8::Isolate* isolate, int sessionId,
}
bool hasBody = hasBodyValue->ToBoolean(isolate)->Value();
- if (jsonML->Length() && !substituteObjectTags(sessionId, groupName, context,
- jsonML, maxDepth)) {
+ std::unique_ptr<protocol::ListValue> protocolJsonML;
+ if (!substituteObjectTags(sessionId, groupName, context, jsonML, maxDepth,
+ &protocolJsonML)) {
return;
}
- v8::Local<v8::String> header;
- if (!v8::JSON::Stringify(context, jsonML).ToLocal(&header)) {
- reportError(context, tryCatch);
- return;
- }
+ std::vector<uint8_t> json;
+ v8_crdtp::json::ConvertCBORToJSON(
+ v8_crdtp::SpanFrom(protocolJsonML->Serialize()), &json);
+ v8_inspector::StringView serialized(json.data(), json.size());
+ String16 header = toString16(serialized);
v8::Local<v8::Function> bodyFunction;
if (hasBody) {
@@ -396,9 +554,7 @@ void generateCustomPreview(v8::Isolate* isolate, int sessionId,
return;
}
}
- *preview = CustomPreview::create()
- .setHeader(toProtocolString(isolate, header))
- .build();
+ *preview = CustomPreview::create().setHeader(header).build();
if (!bodyFunction.IsEmpty()) {
V8InspectorImpl* inspector =
static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
diff --git a/deps/v8/src/inspector/injected-script.cc b/deps/v8/src/inspector/injected-script.cc
index 0d14be4660b..7dc58dc2813 100644
--- a/deps/v8/src/inspector/injected-script.cc
+++ b/deps/v8/src/inspector/injected-script.cc
@@ -165,7 +165,7 @@ class InjectedScript::ProtocolPromiseHandler {
static void thenCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
PromiseHandlerTracker::Id handlerId =
static_cast<PromiseHandlerTracker::Id>(
- info.Data().As<v8::Number>()->Value());
+ info.DataV2().As<v8::Value>().As<v8::Number>()->Value());
PromiseHandlerTracker& handlerTracker =
static_cast<V8InspectorImpl*>(
v8::debug::GetInspector(info.GetIsolate()))
@@ -186,7 +186,7 @@ class InjectedScript::ProtocolPromiseHandler {
static void catchCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
PromiseHandlerTracker::Id handlerId =
static_cast<PromiseHandlerTracker::Id>(
- info.Data().As<v8::Number>()->Value());
+ info.DataV2().As<v8::Value>().As<v8::Number>()->Value());
PromiseHandlerTracker& handlerTracker =
static_cast<V8InspectorImpl*>(
v8::debug::GetInspector(info.GetIsolate()))
diff --git a/deps/v8/src/inspector/v8-console-agent-impl.cc b/deps/v8/src/inspector/v8-console-agent-impl.cc
index 1fc082c4a0a..3fd335d257b 100644
--- a/deps/v8/src/inspector/v8-console-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-console-agent-impl.cc
@@ -65,9 +65,12 @@ void V8ConsoleAgentImpl::reportAllMessages() {
// Also, the storage itself can be destroyed and recreated, so re-fetch the
// storage on each iteration.
size_t size = storage->messages().size();
+ uint64_t storageId = storage->id();
for (size_t i = 0; i < size; ++i) {
- if (m_session->inspector()->consoleMessageStorage(
- m_session->contextGroupId()) != storage) {
+ V8ConsoleMessageStorage* inspectorStorage =
+ m_session->inspector()->consoleMessageStorage(
+ m_session->contextGroupId());
+ if (!inspectorStorage || inspectorStorage->id() != storageId) {
break;
}
if (i >= storage->messages().size()) break;
diff --git a/deps/v8/src/inspector/v8-console-message.cc b/deps/v8/src/inspector/v8-console-message.cc
index 684967a2594..da35ae736e0 100644
--- a/deps/v8/src/inspector/v8-console-message.cc
+++ b/deps/v8/src/inspector/v8-console-message.cc
@@ -326,6 +326,7 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend,
V8ConsoleMessageStorage* storage =
inspector->consoleMessageStorage(contextGroupId);
if (!storage) return;
+ uint64_t storageId = storage->id();
if (m_origin == V8MessageOrigin::kException) {
v8::HandleScope scope(inspector->isolate());
@@ -372,7 +373,11 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend,
if (m_origin == V8MessageOrigin::kConsole) {
std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>>
arguments = wrapArguments(session, generatePreview);
- if (inspector->consoleMessageStorage(contextGroupId) != storage) return;
+ V8ConsoleMessageStorage* inspectorStorage =
+ inspector->consoleMessageStorage(contextGroupId);
+ if (!inspectorStorage || inspectorStorage->id() != storageId) {
+ return;
+ }
if (!arguments) {
arguments =
std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>();
@@ -553,8 +558,9 @@ void V8ConsoleMessage::contextDestroyed(int contextId) {
// ----------------------------
V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8InspectorImpl* inspector,
- int contextGroupId)
- : m_inspector(inspector), m_contextGroupId(contextGroupId) {}
+ int contextGroupId,
+ uint64_t id)
+ : m_inspector(inspector), m_contextGroupId(contextGroupId), m_id(id) {}
V8ConsoleMessageStorage::~V8ConsoleMessageStorage() { clear(); }
@@ -579,6 +585,9 @@ void V8ConsoleMessageStorage::addMessage(
std::unique_ptr<V8ConsoleMessage> message) {
int contextGroupId = m_contextGroupId;
V8InspectorImpl* inspector = m_inspector;
+ // Capture our own id before any reentrant code can run (see
+ // forEachSession() below).
+ uint64_t currentId = id();
if (message->type() == ConsoleAPIType::kClear) clear();
TraceV8ConsoleMessageEvent(message->origin(), message->type());
@@ -590,7 +599,12 @@ void V8ConsoleMessageStorage::addMessage(
}
session->runtimeAgent()->messageAdded(message.get());
});
- if (inspector->consoleMessageStorage(contextGroupId) != this) return;
+
+ V8ConsoleMessageStorage* inspectorStorage =
+ inspector->consoleMessageStorage(contextGroupId);
+ if (!inspectorStorage || inspectorStorage->id() != currentId) {
+ return;
+ }
DCHECK(m_messages.size() <= maxConsoleMessageCount);
if (m_messages.size() == maxConsoleMessageCount) {
diff --git a/deps/v8/src/inspector/v8-console-message.h b/deps/v8/src/inspector/v8-console-message.h
index 1e25ba11a98..b3c40d8f3a6 100644
--- a/deps/v8/src/inspector/v8-console-message.h
+++ b/deps/v8/src/inspector/v8-console-message.h
@@ -113,10 +113,13 @@ class V8ConsoleMessage {
class V8ConsoleMessageStorage {
public:
- V8ConsoleMessageStorage(V8InspectorImpl*, int contextGroupId);
+ V8ConsoleMessageStorage(V8InspectorImpl*, int contextGroupId, uint64_t id);
~V8ConsoleMessageStorage();
int contextGroupId() { return m_contextGroupId; }
+ // A monotonically increasing id assigned by V8InspectorImpl when this
+ // storage instance was created.
+ uint64_t id() const { return m_id; }
const std::deque<std::unique_ptr<V8ConsoleMessage>>& messages() const {
return m_messages;
}
@@ -139,6 +142,7 @@ class V8ConsoleMessageStorage {
private:
V8InspectorImpl* m_inspector;
int m_contextGroupId;
+ uint64_t m_id;
int m_estimatedSize = 0;
std::deque<std::unique_ptr<V8ConsoleMessage>> m_messages;
diff --git a/deps/v8/src/inspector/v8-console.cc b/deps/v8/src/inspector/v8-console.cc
index b65149e7d0d..4679f5fe420 100644
--- a/deps/v8/src/inspector/v8-console.cc
+++ b/deps/v8/src/inspector/v8-console.cc
@@ -561,8 +561,11 @@ v8::Local<v8::ObjectTemplate> V8Console::taskTemplate() {
v8::Local<v8::FunctionTemplate> consTemplate =
v8::FunctionTemplate::New(isolate);
v8::Local<v8::ObjectTemplate> taskTemplate = consTemplate->InstanceTemplate();
+ v8::Local<v8::Signature> signature =
+ v8::Signature::New(isolate, consTemplate);
v8::Local<v8::FunctionTemplate> funcTemplate =
- v8::FunctionTemplate::New(isolate, &TaskInfo::runTask);
+ v8::FunctionTemplate::New(isolate, &TaskInfo::runTask,
+ v8::Local<v8::Value>(), signature);
taskTemplate->Set(isolate, "run", funcTemplate);
m_taskTemplate.Reset(isolate, taskTemplate);
@@ -594,10 +597,6 @@ void TaskInfo::runTask(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Local<v8::Function> function = info[0].As<v8::Function>();
v8::Local<v8::Object> task = info.This();
- if (!task->IsApiWrapper()) {
- isolate->ThrowError("'run' called with illegal receiver.");
- return;
- }
TaskInfo* taskInfo =
v8::Object::Unwrap<TaskInfo::kPointerTag, TaskInfo>(isolate, task);
if (!taskInfo) {
@@ -984,7 +983,7 @@ static bool isCommandLineAPIGetter(const String16& name) {
void V8Console::CommandLineAPIScope::accessorGetterCallback(
v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
v8::Local<v8::Value> data0;
if (!data->Get(context, kCommandLineAPIIndex).ToLocal(&data0) ||
!data0->IsObject()) {
@@ -1014,7 +1013,7 @@ void V8Console::CommandLineAPIScope::accessorSetterCallback(
v8::Local<v8::Name> name, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
v8::Local<v8::Value> data0;
if (!data->Get(context, kCommandLineAPIIndex).ToLocal(&data0) ||
!data0->IsObject()) {
diff --git a/deps/v8/src/inspector/v8-console.h b/deps/v8/src/inspector/v8-console.h
index 956a53b57df..f6df378d2b9 100644
--- a/deps/v8/src/inspector/v8-console.h
+++ b/deps/v8/src/inspector/v8-console.h
@@ -15,6 +15,7 @@
#include "include/v8-traced-handle.h"
#include "src/base/macros.h"
#include "src/debug/interface-types.h"
+#include "src/sandbox/cppheap-pointer-tag.h"
#include "v8-isolate.h"
namespace v8 {
@@ -34,7 +35,7 @@ class V8Console final : public v8::Object::Wrappable,
public v8::debug::ConsoleDelegate {
public:
static constexpr v8::CppHeapPointerTag kPointerTag =
- v8::CppHeapPointerTag::kInspectorV8ConsoleTag;
+ v8::internal::kInspectorV8ConsoleTag;
v8::Local<v8::Object> wrapConsole(v8::Local<v8::Context> context);
void Trace(cppgc::Visitor* visitor) const override;
@@ -137,7 +138,7 @@ class V8Console final : public v8::Object::Wrappable,
template <void (V8Console::*func)(const v8::FunctionCallbackInfo<v8::Value>&)>
static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
V8Console* console = v8::Object::Unwrap<kPointerTag, V8Console>(
- info.GetIsolate(), info.Data().As<v8::Object>());
+ info.GetIsolate(), info.DataV2().As<v8::Value>().As<v8::Object>());
CHECK_NOT_NULL(console);
CHECK_NOT_NULL(console->m_inspector);
(console->*func)(info);
@@ -145,7 +146,7 @@ class V8Console final : public v8::Object::Wrappable,
template <void (V8Console::*func)(const v8::FunctionCallbackInfo<v8::Value>&,
int)>
static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
v8::Local<v8::Value> console_value;
if (!data->Get(context, 0).ToLocal(&console_value) ||
@@ -167,7 +168,7 @@ class V8Console final : public v8::Object::Wrappable,
template <void (V8Console::*func)(const v8::debug::ConsoleCallArguments&,
const v8::debug::ConsoleContext&)>
static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
v8::Local<v8::Value> console_value;
if (!data->Get(context, 0).ToLocal(&console_value) ||
@@ -266,7 +267,7 @@ class V8Console final : public v8::Object::Wrappable,
class TaskInfo : public v8::Object::Wrappable {
public:
static constexpr v8::CppHeapPointerTag kPointerTag =
- v8::CppHeapPointerTag::kInspectorTaskInfoTag;
+ v8::internal::kInspectorTaskInfoTag;
TaskInfo(v8::Isolate* isolate, V8Console* console);
~TaskInfo() override;
diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
index 2438b05cfdb..1c7507ddda3 100644
--- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
@@ -371,6 +371,9 @@ Response buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator,
.setColumnNumber(end.GetColumnNumber())
.build());
}
+ if (!iterator->DeclaresLocals()) {
+ scope->setEmpty(true);
+ }
(*scopes)->emplace_back(std::move(scope));
}
return Response::Success();
@@ -538,6 +541,7 @@ Response V8DebuggerAgentImpl::disable() {
m_debugger->setAsyncCallStackDepth(this, 0);
clearBreakDetails();
m_skipAllPauses = false;
+ m_skipAllPausesFromEmbedder = false;
m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
m_state->remove(DebuggerAgentState::blackboxPattern);
m_enableState = kDisabled;
@@ -567,8 +571,7 @@ void V8DebuggerAgentImpl::restore() {
m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
setPauseOnExceptionsImpl(pauseState);
- m_skipAllPauses =
- m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
+ updateSkipAllPauses();
int asyncCallStackDepth = 0;
m_state->getInteger(DebuggerAgentState::asyncCallStackDepth,
@@ -599,10 +602,21 @@ Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip);
- m_skipAllPauses = skip;
+ updateSkipAllPauses();
return Response::Success();
}
+void V8DebuggerAgentImpl::setSkipAllPausesForInternalUse(bool skip) {
+ m_skipAllPausesFromEmbedder = skip;
+ updateSkipAllPauses();
+}
+
+void V8DebuggerAgentImpl::updateSkipAllPauses() {
+ m_skipAllPauses =
+ m_skipAllPausesFromEmbedder ||
+ m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
+}
+
namespace {
class Matcher {
diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.h b/deps/v8/src/inspector/v8-debugger-agent-impl.h
index 09c85bd7deb..f250803a00e 100644
--- a/deps/v8/src/inspector/v8-debugger-agent-impl.h
+++ b/deps/v8/src/inspector/v8-debugger-agent-impl.h
@@ -58,6 +58,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
V8DebuggerAgentImpl& operator=(const V8DebuggerAgentImpl&) = delete;
void restore();
void stop();
+ void setSkipAllPausesForInternalUse(bool skip);
// Part of the protocol.
Response enable(std::optional<double> maxScriptsCacheSize,
@@ -300,8 +301,10 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> breakAuxData);
void popBreakDetails();
+ void updateSkipAllPauses();
bool m_skipAllPauses = false;
+ bool m_skipAllPausesFromEmbedder = false;
bool m_breakpointsActive = false;
bool m_instrumentationFinished = true;
bool m_skipAnonymousScripts = false;
diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc
index 346c6c94a6d..e163778471a 100644
--- a/deps/v8/src/inspector/v8-debugger.cc
+++ b/deps/v8/src/inspector/v8-debugger.cc
@@ -812,6 +812,7 @@ v8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
v8::Local<v8::Context> context, v8::Local<v8::Value> value,
ScopeTargetKind kind) {
std::unique_ptr<v8::debug::ScopeIterator> iterator;
+ v8::Local<v8::Function> generator_function;
switch (kind) {
case FUNCTION:
iterator = v8::debug::ScopeIterator::CreateForFunction(
@@ -822,6 +823,7 @@ v8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
v8::debug::GeneratorObject::Cast(value);
if (!generatorObject->IsSuspended()) return v8::MaybeLocal<v8::Value>();
+ generator_function = generatorObject->Function();
iterator = v8::debug::ScopeIterator::CreateForGeneratorObject(
m_isolate, value.As<v8::Object>());
break;
@@ -832,7 +834,25 @@ v8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
return v8::MaybeLocal<v8::Value>();
}
- for (; !iterator->Done(); iterator->Advance()) {
+ // [[Scopes]] reflects the runtime context chain: For generators, list the
+ // generator's own scopes up to its function scope, then continue with the
+ // closure's context chain like for functions (instead of the lexical outer
+ // scopes). Empty scopes are omitted, except for a generator's own scope.
+ auto advance = [&]() {
+ if (!generator_function.IsEmpty() &&
+ iterator->GetType() == v8::debug::ScopeIterator::ScopeTypeLocal) {
+ iterator = v8::debug::ScopeIterator::CreateForFunction(
+ m_isolate, generator_function);
+ generator_function.Clear();
+ } else {
+ iterator->Advance();
+ }
+ };
+ for (; iterator && !iterator->Done(); advance()) {
+ if (iterator->GetType() != v8::debug::ScopeIterator::ScopeTypeLocal &&
+ !iterator->DeclaresLocals()) {
+ continue;
+ }
v8::Local<v8::Object> scope = v8::Object::New(m_isolate);
if (!addInternalObject(context, scope, V8InternalValueType::kScope)) {
return v8::MaybeLocal<v8::Value>();
diff --git a/deps/v8/src/inspector/v8-inspector-impl.cc b/deps/v8/src/inspector/v8-inspector-impl.cc
index e4bd1415e26..5f89266767b 100644
--- a/deps/v8/src/inspector/v8-inspector-impl.cc
+++ b/deps/v8/src/inspector/v8-inspector-impl.cc
@@ -132,12 +132,14 @@ V8ConsoleMessageStorage* V8InspectorImpl::ensureConsoleMessageStorage(
int contextGroupId) {
auto storageIt = m_consoleStorageMap.find(contextGroupId);
if (storageIt == m_consoleStorageMap.end()) {
- storageIt = m_consoleStorageMap
- .insert(std::make_pair(
- contextGroupId,
- std::unique_ptr<V8ConsoleMessageStorage>(
- new V8ConsoleMessageStorage(this, contextGroupId))))
- .first;
+ storageIt =
+ m_consoleStorageMap
+ .insert(std::make_pair(
+ contextGroupId,
+ std::unique_ptr<V8ConsoleMessageStorage>(
+ new V8ConsoleMessageStorage(this, contextGroupId,
+ m_nextConsoleStorageId++))))
+ .first;
}
return storageIt->second.get();
}
diff --git a/deps/v8/src/inspector/v8-inspector-impl.h b/deps/v8/src/inspector/v8-inspector-impl.h
index 0bfffc30377..249fd331424 100644
--- a/deps/v8/src/inspector/v8-inspector-impl.h
+++ b/deps/v8/src/inspector/v8-inspector-impl.h
@@ -205,6 +205,10 @@ class V8InspectorImpl : public V8Inspector {
using ConsoleStorageMap =
std::unordered_map<int, std::unique_ptr<V8ConsoleMessageStorage>>;
ConsoleStorageMap m_consoleStorageMap;
+ // Monotonically increasing counter used to tag each newly-created
+ // V8ConsoleMessageStorage with a unique id. 64 bit should ensure this does
+ // not realistically wrap around.
+ uint64_t m_nextConsoleStorageId = 1;
std::unordered_map<int, int> m_contextIdToGroupIdMap;
std::map<std::pair<int64_t, int64_t>, int> m_uniqueIdToContextId;
diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.cc b/deps/v8/src/inspector/v8-inspector-session-impl.cc
index 92b96d44847..9ec526f64e9 100644
--- a/deps/v8/src/inspector/v8-inspector-session-impl.cc
+++ b/deps/v8/src/inspector/v8-inspector-session-impl.cc
@@ -507,6 +507,10 @@ void V8InspectorSessionImpl::setSkipAllPauses(bool skip) {
m_debuggerAgent->setSkipAllPauses(skip);
}
+void V8InspectorSessionImpl::setSkipAllPausesForInternalUse(bool skip) {
+ m_debuggerAgent->setSkipAllPausesForInternalUse(skip);
+}
+
void V8InspectorSessionImpl::resume(bool terminateOnResume) {
m_debuggerAgent->resume(terminateOnResume);
}
diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.h b/deps/v8/src/inspector/v8-inspector-session-impl.h
index f7701e48af8..8a87b951242 100644
--- a/deps/v8/src/inspector/v8-inspector-session-impl.h
+++ b/deps/v8/src/inspector/v8-inspector-session-impl.h
@@ -105,6 +105,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
void cancelPauseOnNextStatement() override;
void breakProgram(StringView breakReason, StringView breakDetails) override;
void setSkipAllPauses(bool) override;
+ void setSkipAllPausesForInternalUse(bool) override;
void resume(bool terminateOnResume = false) override;
void stepOver() override;
std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.cc b/deps/v8/src/inspector/v8-runtime-agent-impl.cc
index b17432ca819..0120bbd5cf4 100644
--- a/deps/v8/src/inspector/v8-runtime-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-runtime-agent-impl.cc
@@ -871,18 +871,20 @@ Response V8RuntimeAgentImpl::getHeapUsage(double* out_usedSize,
*out_usedSize = stats.used_heap_size();
*out_totalSize = stats.total_heap_size();
*out_backingStorageSize = stats.external_memory();
- if (v8::CppHeap* cppHeap = m_inspector->isolate()->GetCppHeap()) {
- cppgc::HeapStatistics cppStats =
- cppHeap->CollectStatistics(cppgc::HeapStatistics::DetailLevel::kBrief);
- *out_embedderHeapUsedSize = cppStats.used_size_bytes;
- } else {
- *out_embedderHeapUsedSize = 0;
- }
+ v8::CppHeap* cppHeap = m_inspector->isolate()->GetCppHeap();
+ cppgc::HeapStatistics cppStats =
+ cppHeap->CollectStatistics(cppgc::HeapStatistics::DetailLevel::kBrief);
+ *out_embedderHeapUsedSize = cppStats.used_size_bytes;
return Response::Success();
}
void V8RuntimeAgentImpl::terminateExecution(
std::unique_ptr<TerminateExecutionCallback> callback) {
+ if (m_session->clientTrustLevel() != V8Inspector::kFullyTrusted) {
+ callback->sendFailure(Response::ServerError(
+ "Runtime.terminateExecution is not allowed for untrusted clients"));
+ return;
+ }
v8::HandleScope handles(m_inspector->isolate());
v8::Local<v8::Context> defaultContext =
m_inspector->client()->ensureDefaultContextInGroup(
@@ -967,7 +969,8 @@ void V8RuntimeAgentImpl::bindingCallback(
int contextId = InspectedContext::contextId(isolate->GetCurrentContext());
int contextGroupId = inspector->contextGroupId(contextId);
- String16 name = toProtocolString(isolate, info.Data().As<v8::String>());
+ String16 name =
+ toProtocolString(isolate, info.DataV2().As<v8::Value>().As<v8::String>());
String16 payload = toProtocolString(isolate, info[0].As<v8::String>());
inspector->forEachSession(
@@ -1141,9 +1144,11 @@ Response V8RuntimeAgentImpl::enable() {
// Also, the storage itself can be destroyed and recreated, so re-fetch the
// storage on each iteration.
size_t size = storage->messages().size();
+ uint64_t storageId = storage->id();
for (size_t i = 0; i < size; ++i) {
- if (m_inspector->consoleMessageStorage(m_session->contextGroupId()) !=
- storage) {
+ V8ConsoleMessageStorage* inspectorStorage =
+ m_inspector->consoleMessageStorage(m_session->contextGroupId());
+ if (!inspectorStorage || inspectorStorage->id() != storageId) {
break;
}
if (i >= storage->messages().size()) break;
diff --git a/deps/v8/src/inspector/value-mirror.cc b/deps/v8/src/inspector/value-mirror.cc
index 357c9a65712..ac78cea1653 100644
--- a/deps/v8/src/inspector/value-mirror.cc
+++ b/deps/v8/src/inspector/value-mirror.cc
@@ -1420,7 +1420,7 @@ void nativeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate::DisallowJavascriptExecutionScope throwJs(
isolate,
v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
if (!data->Get(context, 0).ToLocal(&name)) return;
if (!data->Get(context, 1).ToLocal(&object) || !object->IsObject()) return;
}
@@ -1458,7 +1458,7 @@ void nativeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate::DisallowJavascriptExecutionScope throwJs(
isolate,
v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
- v8::Local<v8::Array> data = info.Data().As<v8::Array>();
+ v8::Local<v8::Array> data = info.DataV2().As<v8::Value>().As<v8::Array>();
if (!data->Get(context, 0).ToLocal(&name)) return;
if (!data->Get(context, 1).ToLocal(&object) || !object->IsObject()) return;
}
diff --git a/deps/v8/src/interpreter/bytecode-array-builder.cc b/deps/v8/src/interpreter/bytecode-array-builder.cc
index cf500b4831f..d50b594fe21 100644
--- a/deps/v8/src/interpreter/bytecode-array-builder.cc
+++ b/deps/v8/src/interpreter/bytecode-array-builder.cc
@@ -732,6 +732,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
return *this;
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTdzHole() {
+ OutputLdaTdzHole();
+ return *this;
+}
+
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
OutputLdaTrue();
return *this;
@@ -829,14 +834,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
OutputLdaImmutableContextSlot(context, slot_index, depth);
}
} else {
- DCHECK_NE(VariableMode::kConst, variable->mode());
if (variable->scope()->has_context_cells()) {
+ DCHECK_NE(VariableMode::kConst, variable->mode());
if (context.is_current_context() && depth == 0) {
OutputLdaCurrentContextSlot(slot_index);
} else {
OutputLdaContextSlot(context, slot_index, depth);
}
} else {
+ DCHECK(variable->mode() != VariableMode::kConst ||
+ (variable->scope()->is_class_scope() &&
+ variable->scope()->AsClassScope()->class_variable() == variable));
if (context.is_current_context() && depth == 0) {
OutputLdaCurrentContextSlotNoCell(slot_index);
} else {
@@ -1047,6 +1055,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::DefineNamedOwnProperty(
return *this;
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::DefineNamedOwnPropertyInLiteral(
+ Register object, const AstRawString* name, int feedback_slot) {
+ size_t name_index = GetConstantPoolEntry(name);
+ // Ensure that the store operation is in sync with the IC slot kind.
+ DCHECK_EQ(
+ FeedbackSlotKind::kDefineNamedOwn,
+ feedback_vector_spec()->GetKind(FeedbackVector::ToSlot(feedback_slot)));
+ OutputDefineNamedOwnPropertyInLiteral(object, name_index, feedback_slot);
+ return *this;
+}
+
BytecodeArrayBuilder& BytecodeArrayBuilder::SetKeyedProperty(
Register object, Register key, int feedback_slot,
LanguageMode language_mode) {
@@ -1489,20 +1508,21 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
return *this;
}
-BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowReferenceErrorIfHole(
+BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowReferenceErrorIfTdzHole(
const AstRawString* name) {
size_t entry = GetConstantPoolEntry(name);
- OutputThrowReferenceErrorIfHole(entry);
+ OutputThrowReferenceErrorIfTdzHole(entry);
return *this;
}
-BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperNotCalledIfHole() {
- OutputThrowSuperNotCalledIfHole();
+BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperNotCalledIfTdzHole() {
+ OutputThrowSuperNotCalledIfTdzHole();
return *this;
}
-BytecodeArrayBuilder& BytecodeArrayBuilder::ThrowSuperAlreadyCalledIfNotHole() {
- OutputThrowSuperAlreadyCalledIfNotHole();
+BytecodeArrayBuilder&
+BytecodeArrayBuilder::ThrowSuperAlreadyCalledIfNotTdzHole() {
+ OutputThrowSuperAlreadyCalledIfNotTdzHole();
return *this;
}
diff --git a/deps/v8/src/interpreter/bytecode-array-builder.h b/deps/v8/src/interpreter/bytecode-array-builder.h
index 1a131569834..c43d1d0ce6a 100644
--- a/deps/v8/src/interpreter/bytecode-array-builder.h
+++ b/deps/v8/src/interpreter/bytecode-array-builder.h
@@ -103,6 +103,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& LoadUndefined();
BytecodeArrayBuilder& LoadNull();
BytecodeArrayBuilder& LoadTheHole();
+ BytecodeArrayBuilder& LoadTdzHole();
BytecodeArrayBuilder& LoadTrue();
BytecodeArrayBuilder& LoadFalse();
BytecodeArrayBuilder& LoadBoolean(bool value);
@@ -208,6 +209,13 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
const AstRawString* name,
int feedback_slot);
+ // Like DefineNamedOwnProperty, but may only be used for the initializing
+ // store of a property of an object literal created from a boilerplate: the
+ // property exists in the object's map and still holds the uninitialized
+ // value.
+ BytecodeArrayBuilder& DefineNamedOwnPropertyInLiteral(
+ Register object, const AstRawString* name, int feedback_slot);
+
// Set a property keyed by a value in a register, trigger the setters and
// set traps if necessary. The value to be set should be in the
// accumulator.
@@ -492,9 +500,9 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& ReThrow();
BytecodeArrayBuilder& Abort(AbortReason reason);
BytecodeArrayBuilder& Return();
- BytecodeArrayBuilder& ThrowReferenceErrorIfHole(const AstRawString* name);
- BytecodeArrayBuilder& ThrowSuperNotCalledIfHole();
- BytecodeArrayBuilder& ThrowSuperAlreadyCalledIfNotHole();
+ BytecodeArrayBuilder& ThrowReferenceErrorIfTdzHole(const AstRawString* name);
+ BytecodeArrayBuilder& ThrowSuperNotCalledIfTdzHole();
+ BytecodeArrayBuilder& ThrowSuperAlreadyCalledIfNotTdzHole();
BytecodeArrayBuilder& ThrowIfNotSuperConstructor(Register constructor);
// Debugger.
diff --git a/deps/v8/src/interpreter/bytecode-generator.cc b/deps/v8/src/interpreter/bytecode-generator.cc
index ae6d376a8ad..b6b59326301 100644
--- a/deps/v8/src/interpreter/bytecode-generator.cc
+++ b/deps/v8/src/interpreter/bytecode-generator.cc
@@ -2148,13 +2148,13 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
case VariableLocation::LOCAL:
if (variable->binding_needs_init()) {
Register destination(builder()->Local(variable->index()));
- builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
+ builder()->LoadTdzHole().StoreAccumulatorInRegister(destination);
}
break;
case VariableLocation::PARAMETER:
if (variable->binding_needs_init()) {
Register destination(builder()->Parameter(variable->index()));
- builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
+ builder()->LoadTdzHole().StoreAccumulatorInRegister(destination);
}
break;
case VariableLocation::REPL_GLOBAL:
@@ -2163,7 +2163,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
case VariableLocation::CONTEXT:
if (variable->binding_needs_init()) {
DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
- builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
+ builder()->LoadTdzHole().StoreContextSlot(execution_context()->reg(),
variable, 0);
}
break;
@@ -3650,6 +3650,36 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
}
}
+ // Define private accessors early, using only a single call to the runtime for
+ // each pair of corresponding getters and setters, in the order the first
+ // component is declared.
+ for (auto accessors : private_accessors.ordered_accessors()) {
+ RegisterAllocationScope inner_register_scope(this);
+ RegisterList accessors_reg = register_allocator()->NewRegisterList(2);
+ ClassLiteral::Property* getter = accessors.second->getter;
+ ClassLiteral::Property* setter = accessors.second->setter;
+ Variable* accessor_pair_var;
+ if (getter && getter->kind() == ClassLiteral::Property::AUTO_ACCESSOR) {
+ DCHECK_EQ(setter, getter);
+ AutoAccessorInfo* auto_accessor_info = getter->auto_accessor_info();
+ VisitForRegisterValue(auto_accessor_info->generated_getter(),
+ accessors_reg[0]);
+ VisitForRegisterValue(auto_accessor_info->generated_setter(),
+ accessors_reg[1]);
+ accessor_pair_var =
+ auto_accessor_info->property_private_name_proxy()->var();
+ } else {
+ VisitLiteralAccessor(getter, accessors_reg[0]);
+ VisitLiteralAccessor(setter, accessors_reg[1]);
+ accessor_pair_var = getter != nullptr ? getter->private_name_var()
+ : setter->private_name_var();
+ }
+ builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg);
+ DCHECK_NOT_NULL(accessor_pair_var);
+ BuildVariableAssignment(accessor_pair_var, Token::kInit,
+ HoleCheckMode::kElided);
+ }
+
{
RegisterAllocationScope register_scope(this);
RegisterList args = register_allocator()->NewGrowableRegisterList();
@@ -3770,36 +3800,6 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
HoleCheckMode::kElided);
}
- // Define private accessors, using only a single call to the runtime for
- // each pair of corresponding getters and setters, in the order the first
- // component is declared.
- for (auto accessors : private_accessors.ordered_accessors()) {
- RegisterAllocationScope inner_register_scope(this);
- RegisterList accessors_reg = register_allocator()->NewRegisterList(2);
- ClassLiteral::Property* getter = accessors.second->getter;
- ClassLiteral::Property* setter = accessors.second->setter;
- Variable* accessor_pair_var;
- if (getter && getter->kind() == ClassLiteral::Property::AUTO_ACCESSOR) {
- DCHECK_EQ(setter, getter);
- AutoAccessorInfo* auto_accessor_info = getter->auto_accessor_info();
- VisitForRegisterValue(auto_accessor_info->generated_getter(),
- accessors_reg[0]);
- VisitForRegisterValue(auto_accessor_info->generated_setter(),
- accessors_reg[1]);
- accessor_pair_var =
- auto_accessor_info->property_private_name_proxy()->var();
- } else {
- VisitLiteralAccessor(getter, accessors_reg[0]);
- VisitLiteralAccessor(setter, accessors_reg[1]);
- accessor_pair_var = getter != nullptr ? getter->private_name_var()
- : setter->private_name_var();
- }
- builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg);
- DCHECK_NOT_NULL(accessor_pair_var);
- BuildVariableAssignment(accessor_pair_var, Token::kInit,
- HoleCheckMode::kElided);
- }
-
if (expr->instance_members_initializer_function() != nullptr) {
VisitForAccumulatorValue(expr->instance_members_initializer_function());
@@ -4286,8 +4286,13 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForAccumulatorValue(property->value());
if (key->IsStringLiteral()) {
FeedbackSlot slot = feedback_spec()->AddDefineNamedOwnICSlot();
- builder()->DefineNamedOwnProperty(literal, key->AsRawPropertyName(),
- feedback_index(slot));
+ if (clone_object_spread) {
+ builder()->DefineNamedOwnProperty(
+ literal, key->AsRawPropertyName(), feedback_index(slot));
+ } else {
+ builder()->DefineNamedOwnPropertyInLiteral(
+ literal, key->AsRawPropertyName(), feedback_index(slot));
+ }
} else {
FeedbackSlot slot = feedback_spec()->AddDefineKeyedOwnICSlot();
builder()->DefineKeyedOwnProperty(
@@ -4715,7 +4720,7 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
// subsequent expressions assign to the same variable.
builder()->LoadAccumulatorWithRegister(source);
if (VariableNeedsHoleCheckInCurrentBlock(variable, hole_check_mode)) {
- BuildThrowIfHole(variable);
+ BuildThrowIfTdzHole(variable);
}
break;
}
@@ -4731,7 +4736,7 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
// subsequent expressions assign to the same variable.
builder()->LoadAccumulatorWithRegister(source);
if (VariableNeedsHoleCheckInCurrentBlock(variable, hole_check_mode)) {
- BuildThrowIfHole(variable);
+ BuildThrowIfTdzHole(variable);
}
break;
}
@@ -4767,7 +4772,7 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
builder()->LoadContextSlot(context_reg, variable, depth);
if (VariableNeedsHoleCheckInCurrentBlock(variable, hole_check_mode)) {
- BuildThrowIfHole(variable);
+ BuildThrowIfTdzHole(variable);
}
if (is_immutable) {
SetVariableInRegister(variable, acc);
@@ -4789,7 +4794,7 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
local_variable->index(), depth);
if (VariableNeedsHoleCheckInCurrentBlock(local_variable,
hole_check_mode)) {
- BuildThrowIfHole(local_variable);
+ BuildThrowIfTdzHole(local_variable);
}
break;
}
@@ -4819,7 +4824,7 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
int depth = execution_context()->ContextChainDepth(variable->scope());
builder()->LoadModuleVariable(variable->index(), depth);
if (VariableNeedsHoleCheckInCurrentBlock(variable, hole_check_mode)) {
- BuildThrowIfHole(variable);
+ BuildThrowIfTdzHole(variable);
}
break;
}
@@ -4901,12 +4906,12 @@ void BytecodeGenerator::RememberHoleCheckInCurrentBlock(Variable* variable) {
vars_in_hole_check_bitmap_);
}
-void BytecodeGenerator::BuildThrowIfHole(Variable* variable) {
+void BytecodeGenerator::BuildThrowIfTdzHole(Variable* variable) {
if (variable->is_this()) {
DCHECK(variable->mode() == VariableMode::kConst);
- builder()->ThrowSuperNotCalledIfHole();
+ builder()->ThrowSuperNotCalledIfTdzHole();
} else {
- builder()->ThrowReferenceErrorIfHole(variable->raw_name());
+ builder()->ThrowReferenceErrorIfTdzHole(variable->raw_name());
}
RememberHoleCheckInCurrentBlock(variable);
}
@@ -4937,12 +4942,12 @@ void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
//
// Do not remember the hole check because this bytecode throws if 'this' is
// *not* the hole, i.e. the opposite of the TDZ hole check.
- builder()->ThrowSuperAlreadyCalledIfNotHole();
+ builder()->ThrowSuperAlreadyCalledIfNotTdzHole();
} else {
// Perform an initialization check for let/const declared variables.
// E.g. let x = (x = 20); is not allowed.
DCHECK(IsLexicalVariableMode(variable->mode()));
- BuildThrowIfHole(variable);
+ BuildThrowIfTdzHole(variable);
}
}
@@ -7453,6 +7458,7 @@ void BytecodeGenerator::VisitDelete(UnaryOperation* unary) {
DCHECK(!property->IsPrivateReference());
if (property->IsSuperAccess()) {
// Delete of super access is not allowed.
+ BuildThisVariableLoad();
VisitForEffect(property->key());
builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
} else {
diff --git a/deps/v8/src/interpreter/bytecode-generator.h b/deps/v8/src/interpreter/bytecode-generator.h
index 66154184028..bdea0ba4fc6 100644
--- a/deps/v8/src/interpreter/bytecode-generator.h
+++ b/deps/v8/src/interpreter/bytecode-generator.h
@@ -356,7 +356,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
bool VariableNeedsHoleCheckInCurrentBlockForAssignment(
Variable* variable, Token::Value op, HoleCheckMode hole_check_mode);
void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
- void BuildThrowIfHole(Variable* variable);
+ void BuildThrowIfTdzHole(Variable* variable);
void BuildNewLocalActivationContext();
void BuildLocalActivationContextInitialization();
diff --git a/deps/v8/src/interpreter/bytecodes.cc b/deps/v8/src/interpreter/bytecodes.cc
index bbcad9ae2ba..75d8406e24d 100644
--- a/deps/v8/src/interpreter/bytecodes.cc
+++ b/deps/v8/src/interpreter/bytecodes.cc
@@ -270,6 +270,7 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
case Bytecode::kLdaSmi:
case Bytecode::kLdaNull:
case Bytecode::kLdaTheHole:
+ case Bytecode::kLdaTdzHole:
case Bytecode::kLdaConstant:
case Bytecode::kLdaUndefined:
case Bytecode::kLdaGlobal:
@@ -300,7 +301,7 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
case Bytecode::kConstructWithSpread:
case Bytecode::kCreateObjectLiteral:
case Bytecode::kCreateArrayLiteral:
- case Bytecode::kThrowReferenceErrorIfHole:
+ case Bytecode::kThrowReferenceErrorIfTdzHole:
case Bytecode::kGetTemplateObject:
return true;
default:
diff --git a/deps/v8/src/interpreter/bytecodes.h b/deps/v8/src/interpreter/bytecodes.h
index c37a4c662d0..965fa710d21 100644
--- a/deps/v8/src/interpreter/bytecodes.h
+++ b/deps/v8/src/interpreter/bytecodes.h
@@ -90,6 +90,7 @@ namespace interpreter {
V(LdaUndefined, ImplicitRegisterUse::kWriteAccumulator) \
V(LdaNull, ImplicitRegisterUse::kWriteAccumulator) \
V(LdaTheHole, ImplicitRegisterUse::kWriteAccumulator) \
+ V(LdaTdzHole, ImplicitRegisterUse::kWriteAccumulator) \
V(LdaTrue, ImplicitRegisterUse::kWriteAccumulator) \
V(LdaFalse, ImplicitRegisterUse::kWriteAccumulator) \
V(LdaConstant, ImplicitRegisterUse::kWriteAccumulator, \
@@ -193,6 +194,9 @@ namespace interpreter {
V(DefineNamedOwnProperty, ImplicitRegisterUse::kReadAndClobberAccumulator, \
OperandType::kReg, OperandType::kConstantPoolIndex, \
OperandType::kFeedbackSlot) \
+ V(DefineNamedOwnPropertyInLiteral, \
+ ImplicitRegisterUse::kReadAndClobberAccumulator, OperandType::kReg, \
+ OperandType::kConstantPoolIndex, OperandType::kFeedbackSlot) \
V(SetKeyedProperty, ImplicitRegisterUse::kReadAndClobberAccumulator, \
OperandType::kReg, OperandType::kReg, OperandType::kFeedbackSlot) \
V(DefineKeyedOwnProperty, ImplicitRegisterUse::kReadAndClobberAccumulator, \
@@ -481,10 +485,11 @@ namespace interpreter {
V(Throw, ImplicitRegisterUse::kReadAccumulator) \
V(ReThrow, ImplicitRegisterUse::kReadAccumulator) \
V(Return, ImplicitRegisterUse::kReadAccumulator) \
- V(ThrowReferenceErrorIfHole, ImplicitRegisterUse::kReadAccumulator, \
+ V(ThrowReferenceErrorIfTdzHole, ImplicitRegisterUse::kReadAccumulator, \
OperandType::kConstantPoolIndex) \
- V(ThrowSuperNotCalledIfHole, ImplicitRegisterUse::kReadAccumulator) \
- V(ThrowSuperAlreadyCalledIfNotHole, ImplicitRegisterUse::kReadAccumulator) \
+ V(ThrowSuperNotCalledIfTdzHole, ImplicitRegisterUse::kReadAccumulator) \
+ V(ThrowSuperAlreadyCalledIfNotTdzHole, \
+ ImplicitRegisterUse::kReadAccumulator) \
V(ThrowIfNotSuperConstructor, ImplicitRegisterUse::kNone, OperandType::kReg) \
\
/* Generators */ \
diff --git a/deps/v8/src/interpreter/interpreter-generator.cc b/deps/v8/src/interpreter/interpreter-generator.cc
index 40e7050d023..73eee42791a 100644
--- a/deps/v8/src/interpreter/interpreter-generator.cc
+++ b/deps/v8/src/interpreter/interpreter-generator.cc
@@ -116,6 +116,14 @@ IGNITION_HANDLER(LdaTheHole, InterpreterAssembler) {
Dispatch();
}
+// LdaTdzHole
+//
+// Load TdzHole into the accumulator.
+IGNITION_HANDLER(LdaTdzHole, InterpreterAssembler) {
+ SetAccumulator(TdzHoleConstant());
+ Dispatch();
+}
+
// LdaTrue
//
// Load True into the accumulator.
@@ -740,6 +748,17 @@ IGNITION_HANDLER(DefineNamedOwnProperty, InterpreterSetNamedPropertyAssembler) {
SetNamedProperty(Builtin::kDefineNamedOwnIC, NamedPropertyType::kOwn);
}
+// DefineNamedOwnPropertyInLiteral <object> <name_index> <slot>
+//
+// Same as DefineNamedOwnProperty, but only used for the initializing store of
+// a property of an object literal created from a boilerplate, where the
+// property still holds the uninitialized value. Optimizing compilers rely on
+// this.
+IGNITION_HANDLER(DefineNamedOwnPropertyInLiteral,
+ InterpreterSetNamedPropertyAssembler) {
+ SetNamedProperty(Builtin::kDefineNamedOwnIC, NamedPropertyType::kOwn);
+}
+
// SetKeyedProperty <object> <key> <slot>
//
// Calls the KeyedStoreIC at FeedbackVector slot <slot> for <object> and
@@ -3113,14 +3132,17 @@ IGNITION_HANDLER(Return, InterpreterAssembler) {
Return(accumulator);
}
-// ThrowReferenceErrorIfHole <variable_name>
+// ThrowReferenceErrorIfTdzHole <variable_name>
//
-// Throws an exception if the value in the accumulator is TheHole.
-IGNITION_HANDLER(ThrowReferenceErrorIfHole, InterpreterAssembler) {
+// Throws an exception if the value in the accumulator is TdzHole.
+IGNITION_HANDLER(ThrowReferenceErrorIfTdzHole, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
+#ifdef V8_ENABLE_TDZ_HOLE
+ CSA_DCHECK(this, TaggedNotEqual(value, TheHoleConstant()));
+#endif
Label throw_error(this, Label::kDeferred);
- GotoIf(TaggedEqual(value, TheHoleConstant()), &throw_error);
+ GotoIf(TaggedEqual(value, TdzHoleConstant()), &throw_error);
Dispatch();
BIND(&throw_error);
@@ -3134,14 +3156,17 @@ IGNITION_HANDLER(ThrowReferenceErrorIfHole, InterpreterAssembler) {
}
}
-// ThrowSuperNotCalledIfHole
+// ThrowSuperNotCalledIfTdzHole
//
-// Throws an exception if the value in the accumulator is TheHole.
-IGNITION_HANDLER(ThrowSuperNotCalledIfHole, InterpreterAssembler) {
+// Throws an exception if the value in the accumulator is TdzHole.
+IGNITION_HANDLER(ThrowSuperNotCalledIfTdzHole, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
+#ifdef V8_ENABLE_TDZ_HOLE
+ CSA_DCHECK(this, TaggedNotEqual(value, TheHoleConstant()));
+#endif
Label throw_error(this, Label::kDeferred);
- GotoIf(TaggedEqual(value, TheHoleConstant()), &throw_error);
+ GotoIf(TaggedEqual(value, TdzHoleConstant()), &throw_error);
Dispatch();
BIND(&throw_error);
@@ -3153,15 +3178,18 @@ IGNITION_HANDLER(ThrowSuperNotCalledIfHole, InterpreterAssembler) {
}
}
-// ThrowSuperAlreadyCalledIfNotHole
+// ThrowSuperAlreadyCalledIfNotTdzHole
//
// Throws SuperAlreadyCalled exception if the value in the accumulator is not
-// TheHole.
-IGNITION_HANDLER(ThrowSuperAlreadyCalledIfNotHole, InterpreterAssembler) {
+// TdzHole.
+IGNITION_HANDLER(ThrowSuperAlreadyCalledIfNotTdzHole, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
+#ifdef V8_ENABLE_TDZ_HOLE
+ CSA_DCHECK(this, TaggedNotEqual(value, TheHoleConstant()));
+#endif
Label throw_error(this, Label::kDeferred);
- GotoIf(TaggedNotEqual(value, TheHoleConstant()), &throw_error);
+ GotoIf(TaggedNotEqual(value, TdzHoleConstant()), &throw_error);
Dispatch();
BIND(&throw_error);
diff --git a/deps/v8/src/json/json-parser.h b/deps/v8/src/json/json-parser.h
index 8fde4ccff56..af58f3871ae 100644
--- a/deps/v8/src/json/json-parser.h
+++ b/deps/v8/src/json/json-parser.h
@@ -383,6 +383,12 @@ class JsonParser final {
JsonString ScanJsonPropertyKey(JsonContinuation* cont);
base::uc32 ScanUnicodeCharacter();
base::Vector<const Char> GetKeyChars(JsonString key) {
+ // For escaped keys the source range starting at `key.start()` holds the raw
+ // (undecoded) characters while `key.length()` is the decoded length, so the
+ // bytes here do not represent the actual decoded key. Return an empty
+ // vector to signal that the byte-compare transition fast path must be
+ // skipped (see JSDataObjectBuilder::TryFastTransitionToPropertyKey).
+ if (key.has_escape()) return base::Vector<const Char>();
return base::Vector<const Char>(chars_ + key.start(), key.length());
}
Handle<String> MakeString(const JsonString& string,
diff --git a/deps/v8/src/logging/code-events.h b/deps/v8/src/logging/code-events.h
index 2ae521bb620..630e78dd992 100644
--- a/deps/v8/src/logging/code-events.h
+++ b/deps/v8/src/logging/code-events.h
@@ -105,10 +105,12 @@ class LogEventListener {
virtual void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind,
Address pc, int fp_to_sp_delta) = 0;
// These events can happen when 1. an assumption made by optimized code fails
- // or 2. a weakly embedded object dies.
- virtual void CodeDependencyChangeEvent(
- DirectHandle<Code> code, DirectHandle<SharedFunctionInfo> shared,
- const char* reason) = 0;
+ // or 2. a weakly embedded object dies. The latter happens during GC, possibly
+ // on a background thread without a LocalHeap. Therefore this event is not
+ // handlified and no allocation is allowed.
+ virtual void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> shared,
+ const char* reason) = 0;
// Called during GC shortly after any weak references to code objects are
// cleared.
virtual void WeakCodeClearEvent() = 0;
@@ -288,8 +290,8 @@ class Logger {
}
}
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> sfi,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
const char* reason) {
base::RecursiveMutexGuard guard(&mutex_);
for (auto listener : listeners_) {
diff --git a/deps/v8/src/logging/counters-definitions.h b/deps/v8/src/logging/counters-definitions.h
index 3f9098146b2..f5f58a98139 100644
--- a/deps/v8/src/logging/counters-definitions.h
+++ b/deps/v8/src/logging/counters-definitions.h
@@ -80,6 +80,8 @@ namespace internal {
/* Support for PKEYs/PKU by testing result of pkey_alloc(). */ \
HR(wasm_memory_protection_keys_support, V8.WasmMemoryProtectionKeysSupport, \
0, 1, 2) \
+ /* Support for AVX and AVX2 on x64 hardware. */ \
+ HR(wasm_avx2_support, V8.WasmAvx2Support, 0, 1, 2) \
/* Ticks observed in a single Turbofan compilation, in 1K. */ \
HR(turbofan_ticks, V8.TurboFan1KTicks, 0, 100000, 200) \
/* Backtracks observed in a single regexp interpreter execution. */ \
diff --git a/deps/v8/src/logging/log.cc b/deps/v8/src/logging/log.cc
index 773c24fa956..c3dbfeb6833 100644
--- a/deps/v8/src/logging/log.cc
+++ b/deps/v8/src/logging/log.cc
@@ -1712,9 +1712,8 @@ void V8FileLogger::CodeDisableOptEvent(
msg.WriteToLogFile();
}
-void V8FileLogger::ProcessDeoptEvent(DirectHandle<Code> code,
- SourcePosition position, const char* kind,
- const char* reason) {
+void V8FileLogger::ProcessDeoptEvent(Tagged<Code> code, SourcePosition position,
+ const char* kind, const char* reason) {
VMStateIfMainThread<LOGGING> state(isolate_);
MSG_BUILDER();
msg << Event::kCodeDeopt << kNext << Time() << kNext
@@ -1725,7 +1724,7 @@ void V8FileLogger::ProcessDeoptEvent(DirectHandle<Code> code,
int inlining_id = -1;
int script_offset = -1;
if (position.IsKnown()) {
- position.Print(deopt_location, *code);
+ position.Print(deopt_location, code);
inlining_id = position.InliningId();
script_offset = position.ScriptOffset();
} else {
@@ -1742,13 +1741,13 @@ void V8FileLogger::CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind,
if (!is_logging() || !v8_flags.log_deopt) return;
VMStateIfMainThread<LOGGING> state(isolate_);
Deoptimizer::DeoptInfo info = Deoptimizer::ComputeDeoptInfo(*code, pc);
- ProcessDeoptEvent(code, info.position, Deoptimizer::MessageFor(kind),
+ ProcessDeoptEvent(*code, info.position, Deoptimizer::MessageFor(kind),
DeoptimizeReasonToString(info.deopt_reason));
}
-void V8FileLogger::CodeDependencyChangeEvent(
- DirectHandle<Code> code, DirectHandle<SharedFunctionInfo> sfi,
- const char* reason) {
+void V8FileLogger::CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
+ const char* reason) {
if (!is_logging() || !v8_flags.log_deopt) return;
VMStateIfMainThread<LOGGING> state(isolate_);
SourcePosition position(sfi->StartPosition(), -1);
@@ -2195,6 +2194,11 @@ EnumerateCompiledFunctions(Heap* heap) {
// the entire heap here, we may still find them if no GC has cleaned them
// up yet. See crbug.com/385341243 and the associated fix for context.
if (sfi->HasUnpublishedTrustedData(isolate)) continue;
+#if V8_ENABLE_WEBASSEMBLY
+ // Wasm functions don't store wrapper code on the SFI; exported Wasm
+ // functions are recorded via their JSFunction below.
+ if (sfi->HasWasmFunctionData(isolate)) continue;
+#endif // V8_ENABLE_WEBASSEMBLY
if (sfi->is_compiled() && !sfi->HasBytecodeArray()) {
record(sfi, Cast<AbstractCode>(sfi->abstract_code(isolate)));
@@ -2203,12 +2207,17 @@ EnumerateCompiledFunctions(Heap* heap) {
// Given that we no longer iterate over all optimized JSFunctions, we need
// to take care of this here.
Tagged<JSFunction> function = Cast<JSFunction>(obj);
+ Tagged<SharedFunctionInfo> sfi = function->shared();
// TODO(jarin) This leaves out deoptimized code that might still be on the
// stack. Also note that we will not log optimized code objects that are
// only on a type feedback vector. We should make this more precise.
- if (function->HasAttachedOptimizedCode(isolate) &&
- Cast<Script>(function->shared()->script())->HasValidSource()) {
- record(function->shared(), Cast<AbstractCode>(function->code(isolate)));
+ if ((function->HasAttachedOptimizedCode(isolate) &&
+ Cast<Script>(sfi->script())->HasValidSource())
+#if V8_ENABLE_WEBASSEMBLY
+ || sfi->HasWasmExportedFunctionData(isolate)
+#endif // V8_ENABLE_WEBASSEMBLY
+ ) {
+ record(sfi, Cast<AbstractCode>(function->code(isolate)));
}
}
}
diff --git a/deps/v8/src/logging/log.h b/deps/v8/src/logging/log.h
index 49e911dbb40..9f9f63d19df 100644
--- a/deps/v8/src/logging/log.h
+++ b/deps/v8/src/logging/log.h
@@ -206,14 +206,14 @@ class V8FileLogger : public LogEventListener {
DirectHandle<SharedFunctionInfo> shared) override;
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) override;
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> sfi,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
const char* reason) override;
void FeedbackVectorEvent(Tagged<FeedbackVector> vector,
Tagged<AbstractCode> code);
void WeakCodeClearEvent() override {}
- void ProcessDeoptEvent(DirectHandle<Code> code, SourcePosition position,
+ void ProcessDeoptEvent(Tagged<Code> code, SourcePosition position,
const char* kind, const char* reason);
// Emits a code line info record event.
@@ -462,8 +462,8 @@ class V8_EXPORT_PRIVATE CodeEventLogger : public LogEventListener {
void CodeMovingGCEvent() override {}
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) override {}
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> sfi,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
const char* reason) override {}
void WeakCodeClearEvent() override {}
@@ -541,8 +541,8 @@ class ExternalLogEventListener : public LogEventListener {
void CodeMovingGCEvent() override {}
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) override {}
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> sfi,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
const char* reason) override {}
void WeakCodeClearEvent() override {}
diff --git a/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h b/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h
index 8a8e874a87f..1119721c60a 100644
--- a/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h
+++ b/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h
@@ -632,6 +632,22 @@ inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(Register object,
MacroAssembler::StoreTaggedField(value, FieldMemOperand(object, offset));
}
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, ValueNode* constant) {
+ DCHECK(CanStoreTaggedConstant(constant));
+ DCHECK_EQ(constant->Cast<SmiConstant>()->value(), Smi::zero());
+ MacroAssembler::StoreTaggedField(xzr, FieldMemOperand(object, offset));
+}
+
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, Handle<HeapObject> constant) {
+ DCHECK(kSupportsStoreTaggedConstant);
+ TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ MoveTagged(scratch, constant);
+ MacroAssembler::StoreTaggedField(scratch, FieldMemOperand(object, offset));
+}
+
inline void MaglevAssembler::StoreFixedArrayElementNoWriteBarrier(
Register array, Register index, Register value) {
TemporaryRegisterScope temps(this);
@@ -832,6 +848,12 @@ inline void MaglevAssembler::Move(Register dst, Handle<HeapObject> obj) {
}
void MaglevAssembler::MoveTagged(Register dst, Handle<HeapObject> obj) {
#ifdef V8_COMPRESS_POINTERS
+ RootIndex root_index;
+ if (isolate()->roots_table().IsRootHandle(obj, &root_index) &&
+ CanBeImmediate(root_index)) {
+ Mov(dst.W(), Immediate(ReadOnlyRootPtr(root_index)));
+ return;
+ }
Mov(dst.W(), Operand(obj, RelocInfo::COMPRESSED_EMBEDDED_OBJECT));
#else
Mov(dst, Operand(obj));
diff --git a/deps/v8/src/maglev/hamt.h b/deps/v8/src/maglev/hamt.h
index feb7de947f3..ccf595dc8c8 100644
--- a/deps/v8/src/maglev/hamt.h
+++ b/deps/v8/src/maglev/hamt.h
@@ -5,6 +5,8 @@
#ifndef V8_MAGLEV_HAMT_H_
#define V8_MAGLEV_HAMT_H_
+#include <bit>
+
#include "src/base/pointer-with-payload.h"
#include "src/zone/zone.h"
@@ -43,11 +45,14 @@ class HAMTTest;
* the operation is a no-op and the existing structure is returned.
*
* HAMT merge_into(const HAMT& other, Func&& f) const
- * - Time: O(N) (worst case)
- * - Space: O(N) (if copying is needed)
+ * - Time: O(N) (worst case; subtrees shared by pointer are skipped)
+ * - Space: O(C * log32 N), where C is the number of values changed by 'f'
* - Description: Returns a new tree where values in 'this' are updated
* using values from 'other' via the functor 'f'. This operation only
* affects keys present in 'this' (intersection update).
+ * - Note on sharing: Like insert, merging is copy-on-write. Only nodes on
+ * the path to a changed value are copied. If 'f' changes no value, the
+ * operation is a no-op and the existing structure is returned.
*
* Data Structure Diagram:
*
@@ -428,17 +433,20 @@ class HAMT {
return nullptr;
}
+ // Merges list2 into list1, i.e. keys that are only in list2 are dropped.
+ // A leaf is only reallocated if its value, or the value of a leaf behind it
+ // in the chain, actually changes.
template <typename Func>
Leaf* MergeCollisionLists(Zone* zone, Leaf* list1, Leaf* list2,
Func&& f) const {
- Leaf* new_list = nullptr;
- for (Leaf* cur = list1; cur; cur = cur->next) {
- Value* value = FindInCollisionList(list2, cur->key);
- new_list =
- NewLeaf(zone, cur->key, value ? f(cur->value, *value) : cur->value,
- cur->hash, new_list);
+ if (list1 == nullptr) return nullptr;
+ Leaf* new_next = MergeCollisionLists(zone, list1->next, list2, f);
+ Value* value = FindInCollisionList(list2, list1->key);
+ Value merged = value ? f(list1->value, *value) : list1->value;
+ if (new_next == list1->next && merged == list1->value) {
+ return list1;
}
- return new_list;
+ return NewLeaf(zone, list1->key, merged, list1->hash, new_next);
}
template <typename Func>
@@ -458,17 +466,19 @@ class HAMT {
return new_branch;
}
+ // Merges the entries of branch into the collision chain list. Leaves are
+ // reused unless their value changes.
template <typename Func>
Leaf* MergeIntoLeaf(Zone* zone, Leaf* list, Branch* branch, int shift,
Func&& f) const {
- Leaf* new_list = nullptr;
- for (Leaf* cur = list; cur; cur = cur->next) {
- const Value* value = FindHelper(Node(branch), cur->key, cur->hash, shift);
- new_list =
- NewLeaf(zone, cur->key, value ? f(cur->value, *value) : cur->value,
- cur->hash, new_list);
+ if (list == nullptr) return nullptr;
+ Leaf* new_next = MergeIntoLeaf(zone, list->next, branch, shift, f);
+ const Value* value = FindHelper(Node(branch), list->key, list->hash, shift);
+ Value merged = value ? f(list->value, *value) : list->value;
+ if (new_next == list->next && merged == list->value) {
+ return list;
}
- return new_list;
+ return NewLeaf(zone, list->key, merged, list->hash, new_next);
}
template <typename Func>
@@ -489,22 +499,24 @@ class HAMT {
// Both are Branches.
Branch* brA = a.AsBranch();
Branch* brB = b.AsBranch();
- uint32_t mapA = brA->bitmap;
- uint32_t mapB = brB->bitmap;
- Branch* res = CloneBranch(zone, brA);
- Node* res_children = res->children;
- int child_idx = 0;
- for (int i = 0; i < 32; ++i) {
- uint32_t bit = (1U << i);
- if (!(mapA & bit)) continue;
- child_idx++;
- if (!(mapB & bit)) continue;
+ Branch* res = nullptr;
+ for (uint32_t shared_bits = brA->bitmap & brB->bitmap; shared_bits != 0;
+ shared_bits &= shared_bits - 1) {
+ int bit = std::countr_zero(shared_bits);
+ int idx = brA->get_index(bit);
+ Node old_child = brA->get_child(idx);
Node child =
- MergeIntoRec(zone, brA->get_child(brA->get_index(i)),
- brB->get_child(brB->get_index(i)), shift + kBits, f);
- res_children[child_idx - 1] = child;
+ MergeIntoRec(zone, old_child, brB->get_child(brB->get_index(bit)),
+ shift + kBits, f);
+ if (child == old_child) {
+ continue;
+ }
+ if (res == nullptr) {
+ res = CloneBranch(zone, brA);
+ }
+ res->set_child(idx, child);
}
- return Node(res);
+ return res == nullptr ? a : Node(res);
}
};
diff --git a/deps/v8/src/maglev/maglev-assembler-inl.h b/deps/v8/src/maglev/maglev-assembler-inl.h
index 43c8800f2f7..fa05f633704 100644
--- a/deps/v8/src/maglev/maglev-assembler-inl.h
+++ b/deps/v8/src/maglev/maglev-assembler-inl.h
@@ -315,6 +315,36 @@ inline void MaglevAssembler::StoreContextCellSmiValue(Register cell,
value);
}
+// static
+inline bool MaglevAssembler::CanStoreTaggedConstant(ValueNode* value) {
+ if (!kSupportsStoreTaggedConstant) return false;
+ switch (value->opcode()) {
+ case Opcode::kSmiConstant:
+#if V8_TARGET_ARCH_ARM64
+ return value->Cast<SmiConstant>()->value() == Smi::zero();
+#else
+ case Opcode::kHeapConstant:
+ return true;
+ case Opcode::kRootConstant:
+ return CanBeImmediate(value->Cast<RootConstant>()->index());
+#endif // V8_TARGET_ARCH_ARM64
+ default:
+ return false;
+ }
+}
+
+#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, ValueNode* constant) {
+ // See {kSupportsStoreTaggedConstant}.
+ UNREACHABLE();
+}
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, Handle<HeapObject> constant) {
+ UNREACHABLE();
+}
+#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64
+
#if !defined(V8_TARGET_ARCH_RISCV64) && !defined(V8_TARGET_ARCH_LOONG64)
inline void MaglevAssembler::CompareInstanceTypeAndJumpIf(
@@ -849,10 +879,7 @@ inline void MaglevAssembler::CallRuntime(Runtime::FunctionId fid,
}
inline void MaglevAssembler::SetMapAsRoot(Register object, RootIndex map) {
- TemporaryRegisterScope temps(this);
- Register scratch = temps.AcquireScratch();
- LoadTaggedRoot(scratch, map);
- StoreTaggedFieldNoWriteBarrier(object, offsetof(HeapObject, map_), scratch);
+ StoreTaggedRoot(FieldMemOperand(object, offsetof(HeapObject, map_)), map);
}
inline void MaglevAssembler::SmiTagInt32AndJumpIfFail(
@@ -1169,6 +1196,57 @@ inline void MaglevAssembler::AssertElidedWriteBarrier(
#endif // V8_VERIFY_WRITE_BARRIERS
}
+inline void MaglevAssembler::AssertElidedWriteBarrier(
+ Register object, ValueNode* value, RegisterSnapshot snapshot) {
+#if V8_VERIFY_WRITE_BARRIERS
+ if (!v8_flags.verify_write_barriers) return;
+ DCHECK(CanStoreTaggedConstant(value));
+
+ // Smis and read-only roots never need a write barrier.
+ if (value->Is<SmiConstant>()) return;
+ if (value->Is<RootConstant>()) {
+ DCHECK(RootsTable::IsReadOnly(value->Cast<RootConstant>()->index()));
+ return;
+ }
+ AssertElidedWriteBarrier(object, value->Cast<HeapConstant>()->object(),
+ snapshot);
+#endif // V8_VERIFY_WRITE_BARRIERS
+}
+
+inline void MaglevAssembler::AssertElidedWriteBarrier(
+ Register object, compiler::HeapObjectRef value, RegisterSnapshot snapshot) {
+#if V8_VERIFY_WRITE_BARRIERS
+ if (!v8_flags.verify_write_barriers) return;
+
+ ZoneLabelRef ok(this);
+ Label* deferred_write_barrier_check = MakeDeferredCode(
+ [](MaglevAssembler* masm, ZoneLabelRef ok, Register object,
+ compiler::HeapObjectRef value, RegisterSnapshot snapshot) {
+ // Materialize the constant in the scratch register and borrow any
+ // other register for the check; this is verification-only code, so
+ // saving it around the check is fine.
+ TemporaryRegisterScope temps(masm);
+ Register value_reg = temps.AcquireScratch();
+ masm->Move(value_reg, value.object());
+ RegList candidates = kAllocatableGeneralRegisters;
+ candidates.clear(object);
+ Register scratch = candidates.first();
+ masm->Push(scratch);
+ Label done;
+ masm->PreCheckSkippedWriteBarrier(object, value_reg, scratch, &done);
+ masm->CallVerifySkippedWriteBarrierStubSaveRegisters(
+ object, value_reg, SaveFPRegsMode::kSave);
+ masm->bind(&done);
+ masm->Pop(scratch);
+ masm->Jump(*ok);
+ },
+ ok, object, value, snapshot);
+
+ Jump(deferred_write_barrier_check);
+ bind(*ok);
+#endif // V8_VERIFY_WRITE_BARRIERS
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/maglev-assembler.cc b/deps/v8/src/maglev/maglev-assembler.cc
index bf944fe8f08..915452aff1e 100644
--- a/deps/v8/src/maglev/maglev-assembler.cc
+++ b/deps/v8/src/maglev/maglev-assembler.cc
@@ -812,10 +812,10 @@ void AttemptOnStackReplacement(MaglevAssembler* masm,
*no_code_for_osr);
// If tiering is already in progress wait.
- __ LoadByte(scratch1,
- FieldMemOperand(scratch0, offsetof(FeedbackVector, flags_)));
- __ DecodeField<FeedbackVector::OsrTieringInProgressBit>(scratch1);
- __ JumpIfByte(kNotEqual, scratch1, 0, *no_code_for_osr);
+ static_assert(FeedbackVector::OsrTieringInProgressBit::kMask <= 0xff);
+ __ TestUint8AndJumpIfAnySet(
+ FieldMemOperand(scratch0, offsetof(FeedbackVector, flags_)),
+ FeedbackVector::OsrTieringInProgressBit::kMask, *no_code_for_osr);
{
// The osr_urgency exceeds the current loop_depth, signaling an OSR
diff --git a/deps/v8/src/maglev/maglev-assembler.h b/deps/v8/src/maglev/maglev-assembler.h
index ea0e60fc69e..ab934b1ecba 100644
--- a/deps/v8/src/maglev/maglev-assembler.h
+++ b/deps/v8/src/maglev/maglev-assembler.h
@@ -263,6 +263,22 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
ValueCanBeSmi value_can_be_smi);
inline void StoreTaggedFieldNoWriteBarrier(Register object, int offset,
Register value);
+
+ // Whether tagged constants (Smis, read-only roots and compressed heap
+ // objects) can be stored as immediates, i.e. whether the overloads below are
+ // implemented.
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+ static constexpr bool kSupportsStoreTaggedConstant = COMPRESS_POINTERS_BOOL;
+#else
+ static constexpr bool kSupportsStoreTaggedConstant = false;
+#endif
+ // Whether {value} is a constant that {StoreTaggedFieldNoWriteBarrier} can
+ // store as an immediate, without materializing it in a register.
+ static inline bool CanStoreTaggedConstant(ValueNode* value);
+ inline void StoreTaggedFieldNoWriteBarrier(Register object, int offset,
+ ValueNode* constant);
+ inline void StoreTaggedFieldNoWriteBarrier(Register object, int offset,
+ Handle<HeapObject> constant);
inline void StoreTaggedSignedField(Register object, int offset,
Register value);
inline void StoreTaggedSignedField(Register object, int offset,
@@ -272,6 +288,14 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
inline void AssertElidedWriteBarrier(Register object, Register value,
RegisterSnapshot snapshot);
+ // For a constant {value} stored as an immediate (see
+ // {CanStoreTaggedConstant}); the constant is only materialized on the
+ // deferred verification path, so no register is needed for it here.
+ inline void AssertElidedWriteBarrier(Register object, ValueNode* value,
+ RegisterSnapshot snapshot);
+ inline void AssertElidedWriteBarrier(Register object,
+ compiler::HeapObjectRef value,
+ RegisterSnapshot snapshot);
#ifdef V8_ENABLE_SANDBOX
diff --git a/deps/v8/src/maglev/maglev-code-generator.cc b/deps/v8/src/maglev/maglev-code-generator.cc
index db078876f73..273c56c6ecd 100644
--- a/deps/v8/src/maglev/maglev-code-generator.cc
+++ b/deps/v8/src/maglev/maglev-code-generator.cc
@@ -276,9 +276,14 @@ class ParallelMoveResolver {
} else {
DCHECK(source.IsConstant());
DCHECK(IsConstantNode(node->opcode()));
+#ifdef V8_COMPRESS_POINTERS
+ if constexpr (DecompressIfNeeded) {
+ if (needs_decompression == kNeedsDecompression) {
+ node->SetTaggedResultNeedsDecompress();
+ }
+ }
+#endif
materializing_register_moves_[target_reg.code()] = node;
- // No need to update `targets.needs_decompression`, materialization is
- // always decompressed.
return;
}
@@ -321,9 +326,14 @@ class ParallelMoveResolver {
} else {
DCHECK(source.IsConstant());
DCHECK(IsConstantNode(node->opcode()));
+#ifdef V8_COMPRESS_POINTERS
+ if constexpr (DecompressIfNeeded) {
+ if (needs_decompression == kNeedsDecompression) {
+ node->SetTaggedResultNeedsDecompress();
+ }
+ }
+#endif
materializing_stack_slot_moves_.emplace_back(target_slot, node);
- // No need to update `targets.needs_decompression`, materialization is
- // always decompressed.
return;
}
diff --git a/deps/v8/src/maglev/maglev-compilation-info.cc b/deps/v8/src/maglev/maglev-compilation-info.cc
index 4405b9b996f..cf7073c99d4 100644
--- a/deps/v8/src/maglev/maglev-compilation-info.cc
+++ b/deps/v8/src/maglev/maglev-compilation-info.cc
@@ -65,6 +65,43 @@ static bool SpecializeToFunctionContext(
} // namespace
+void MaglevCompilationInfo::InitializeSpecializationContext() {
+#ifdef DEBUG
+ specialization_context_initialized_ = true;
+#endif
+ if (!v8_flags.always_specialize_for_script_context || toplevel_is_osr()) {
+ return;
+ }
+ compiler::JSFunctionRef func_ref = compiler::MakeRefAssumeMemoryFence(
+ broker_, broker_->CanonicalPersistentHandle(toplevel_function_));
+ compiler::ContextRef current = func_ref.context(broker_);
+ if (current.map(broker_).instance_type() == NATIVE_CONTEXT_TYPE) {
+ return;
+ }
+ if (specialize_to_function_context_) {
+ specialization_context_ = current;
+ specialization_context_distance_ = 0;
+ return;
+ }
+ size_t distance = 0;
+ while (true) {
+ InstanceType instance_type = current.map(broker_).instance_type();
+ if (instance_type == NATIVE_CONTEXT_TYPE) {
+ break;
+ }
+ if (instance_type == MODULE_CONTEXT_TYPE ||
+ instance_type == SCRIPT_CONTEXT_TYPE) {
+ specialization_context_ = current;
+ specialization_context_distance_ = distance;
+ return;
+ }
+ size_t step = 1;
+ current = current.previous(broker_, &step);
+ if (step != 0) break;
+ distance++;
+ }
+}
+
MaglevCompilationInfo::MaglevCompilationInfo(
Isolate* isolate, IndirectHandle<JSFunction> function,
BytecodeOffset osr_offset, std::optional<compiler::JSHeapBroker*> js_broker,
diff --git a/deps/v8/src/maglev/maglev-compilation-info.h b/deps/v8/src/maglev/maglev-compilation-info.h
index e05d1201a67..383defe276a 100644
--- a/deps/v8/src/maglev/maglev-compilation-info.h
+++ b/deps/v8/src/maglev/maglev-compilation-info.h
@@ -8,6 +8,7 @@
#include <memory>
#include <optional>
+#include "src/compiler/heap-refs.h"
#include "src/flags/flags.h"
#include "src/handles/handles.h"
#include "src/handles/maybe-handles.h"
@@ -175,7 +176,8 @@ class MaglevCompilationInfo final {
bool trace_json_enabled() const { return trace_json_enabled_; }
bool has_graph_labeller() const { return !!graph_labeller_; }
- void set_graph_labeller(MaglevGraphLabeller* graph_labeller);
+ V8_EXPORT_PRIVATE void set_graph_labeller(
+ MaglevGraphLabeller* graph_labeller);
MaglevGraphLabeller* graph_labeller() const {
DCHECK(has_graph_labeller());
return graph_labeller_.get();
@@ -192,6 +194,17 @@ class MaglevCompilationInfo final {
return specialize_to_function_context_;
}
+ void InitializeSpecializationContext();
+
+ compiler::OptionalContextRef specialization_context() const {
+ DCHECK(specialization_context_initialized_);
+ return specialization_context_;
+ }
+ size_t specialization_context_distance() const {
+ DCHECK(specialization_context_initialized_);
+ return specialization_context_distance_;
+ }
+
// Must be called from within a MaglevCompilationHandleScope. Transfers owned
// handles (e.g. shared_, function_) to the new scope.
void ReopenAndCanonicalizeHandlesInNewScope(Isolate* isolate);
@@ -280,6 +293,12 @@ class MaglevCompilationInfo final {
// contexts.
const bool specialize_to_function_context_;
+ compiler::OptionalContextRef specialization_context_;
+ size_t specialization_context_distance_ = 0;
+#ifdef DEBUG
+ bool specialization_context_initialized_ = false;
+#endif
+
// 1) PersistentHandles created via PersistentHandlesScope inside of
// CompilationHandleScope.
// 2) Owned by MaglevCompilationInfo.
diff --git a/deps/v8/src/maglev/maglev-graph-builder.cc b/deps/v8/src/maglev/maglev-graph-builder.cc
index 0995c6cf3b7..b0bca8d4128 100644
--- a/deps/v8/src/maglev/maglev-graph-builder.cc
+++ b/deps/v8/src/maglev/maglev-graph-builder.cc
@@ -112,6 +112,20 @@ class FunctionContextSpecialization final : public AllStatic {
if (HeapConstant* n = context->TryCast<HeapConstant>()) {
return n->ref().AsContext().previous(unit->broker(), depth);
}
+ if (v8_flags.always_specialize_for_script_context) {
+ if (InitialValue* n = context->TryCast<InitialValue>()) {
+ if (!unit->info()->toplevel_is_osr() &&
+ n->source() == interpreter::Register::current_context()) {
+ if (compiler::OptionalContextRef outer =
+ unit->info()->specialization_context()) {
+ if (*depth >= unit->info()->specialization_context_distance()) {
+ *depth -= unit->info()->specialization_context_distance();
+ return outer->previous(unit->broker(), depth);
+ }
+ }
+ }
+ }
+ }
return {};
}
};
@@ -185,7 +199,7 @@ ValueNode* MaglevGraphBuilder::TryGetParentContext(ValueNode* node) {
// Attempts to walk up the context chain through the graph in order to reduce
// depth and thus the number of runtime loads.
void MaglevGraphBuilder::MinimizeContextChainDepth(
- ValueNode** context, size_t* depth, compiler::ScopeInfoRef* scope_info) {
+ ValueNode** context, size_t* depth, ContextScopeInfo* scope_info) {
while (*depth > 0) {
ValueNode* parent_context = TryGetParentContext(*context);
if (parent_context == nullptr) return;
@@ -765,13 +779,22 @@ ValueNode* MaglevGraphBuilder::GetInlinedArgument(int i) {
void MaglevGraphBuilder::BuildRegisterFrameInitialization(
ValueNode* context, ValueNode* closure, ValueNode* new_target) {
- if (closure == nullptr &&
- compilation_unit_->info()->specialize_to_function_context()) {
- compiler::JSFunctionRef function = compiler::MakeRefAssumeMemoryFence(
- broker(), broker()->CanonicalPersistentHandle(
- compilation_unit_->info()->toplevel_function()));
- closure = GetConstant(function);
- context = GetConstant(function.context(broker()));
+ if (closure == nullptr) {
+ if (compilation_unit_->info()->specialize_to_function_context()) {
+ compiler::JSFunctionRef function = compiler::MakeRefAssumeMemoryFence(
+ broker(), broker()->CanonicalPersistentHandle(
+ compilation_unit_->info()->toplevel_function()));
+ closure = GetConstant(function);
+ context = GetConstant(function.context(broker()));
+ } else if (v8_flags.always_specialize_for_script_context &&
+ !compilation_unit_->info()->toplevel_is_osr() &&
+ compilation_unit_->info()->specialization_context_distance() ==
+ 0) {
+ if (compiler::OptionalContextRef outer =
+ compilation_unit_->info()->specialization_context()) {
+ context = GetConstant(*outer);
+ }
+ }
}
auto InitializeRegister = [&](interpreter::Register reg,
@@ -2596,6 +2619,10 @@ ReduceResult MaglevGraphBuilder::VisitLdaTheHole() {
SetAccumulator(GetRootConstant(RootIndex::kTheHoleValue));
return ReduceResult::Done();
}
+ReduceResult MaglevGraphBuilder::VisitLdaTdzHole() {
+ SetAccumulator(GetRootConstant(RootIndex::kTdzHoleValue));
+ return ReduceResult::Done();
+}
ReduceResult MaglevGraphBuilder::VisitLdaTrue() {
SetAccumulator(GetRootConstant(RootIndex::kTrueValue));
return ReduceResult::Done();
@@ -2630,7 +2657,7 @@ MaglevGraphBuilder::TrySpecializeLoadContextSlotToFunctionContext(
// won't change anymore.
//
// See also: JSContextSpecialization::ReduceJSLoadContext.
- if (slot_value.IsTheHole()) return {};
+ if (slot_value.IsTdzHole()) return {};
if (mode == VariableMode::kVar && slot_value.IsUndefined()) return {};
if (IsPrivateMethodOrAccessorVariableMode(mode) &&
slot_value.IsUndefined()) {
@@ -2649,7 +2676,7 @@ ValueNode* MaglevGraphBuilder::TrySpecializeLoadContextCell(
compiler::ContextRef context =
context_node->Cast<HeapConstant>()->ref().AsContext();
auto maybe_value = context.get(broker(), index);
- if (!maybe_value || maybe_value->IsTheHole() ||
+ if (!maybe_value || maybe_value->IsTdzHole() ||
maybe_value->IsUndefinedContextCell()) {
return {};
}
@@ -2760,7 +2787,7 @@ MaybeReduceResult MaglevGraphBuilder::TrySpecializeStoreContextCell(
compiler::ContextRef context_ref =
context->Cast<HeapConstant>()->ref().AsContext();
auto maybe_value = context_ref.get(broker(), index);
- if (!maybe_value || maybe_value->IsTheHole() ||
+ if (!maybe_value || maybe_value->IsTdzHole() ||
maybe_value->IsUndefinedContextCell()) {
DCHECK_EQ(assigned, kMaybeAssigned);
return AddNewNode<StoreContextSlotWithWriteBarrier>({context, value},
@@ -2893,14 +2920,14 @@ ReduceResult MaglevGraphBuilder::StoreAndCacheContextSlot(
ReduceResult MaglevGraphBuilder::BuildLoadContextSlot(
ValueNode* context, size_t depth, int slot_index, ContextMode context_mode,
- compiler::ScopeInfoRef scope_info) {
+ ContextScopeInfo scope_info) {
context = GetContextAtDepth(context, depth, &scope_info);
return LoadAndCacheContextSlot(context, slot_index, context_mode, scope_info);
}
ReduceResult MaglevGraphBuilder::BuildStoreContextSlot(
ValueNode* context, size_t depth, int slot_index, ValueNode* value,
- ContextMode context_mode, compiler::ScopeInfoRef scope_info) {
+ ContextMode context_mode, ContextScopeInfo scope_info) {
context = GetContextAtDepth(context, depth, &scope_info);
return StoreAndCacheContextSlot(context, slot_index, value, context_mode,
scope_info);
@@ -2911,11 +2938,9 @@ ReduceResult MaglevGraphBuilder::VisitLdaContextSlotNoCell() {
int slot_index = iterator_.GetContextSlotOperand(1);
size_t depth = iterator_.GetUnsignedImmediateOperand(2);
ValueNode* value;
- GET_VALUE(
- value,
- BuildLoadContextSlot(
- context, depth, slot_index, ContextMode::kNoContextCells,
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value()));
+ GET_VALUE(value, BuildLoadContextSlot(
+ context, depth, slot_index, ContextMode::kNoContextCells,
+ register_scope_infos_[iterator_.GetRegisterOperand(0)]));
SetAccumulator(value);
return ReduceResult::Done();
}
@@ -2924,11 +2949,10 @@ ReduceResult MaglevGraphBuilder::VisitLdaContextSlot() {
int slot_index = iterator_.GetContextSlotOperand(1);
size_t depth = iterator_.GetUnsignedImmediateOperand(2);
ValueNode* value;
- GET_VALUE(
- value,
- BuildLoadContextSlot(
- context, depth, slot_index, ContextMode::kHasContextCells,
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value()));
+ GET_VALUE(value,
+ BuildLoadContextSlot(
+ context, depth, slot_index, ContextMode::kHasContextCells,
+ register_scope_infos_[iterator_.GetRegisterOperand(0)]));
SetAccumulator(value);
return ReduceResult::Done();
}
@@ -2937,11 +2961,9 @@ ReduceResult MaglevGraphBuilder::VisitLdaImmutableContextSlot() {
int slot_index = iterator_.GetContextSlotOperand(1);
size_t depth = iterator_.GetUnsignedImmediateOperand(2);
ValueNode* value;
- GET_VALUE(
- value,
- BuildLoadContextSlot(
- context, depth, slot_index, ContextMode::kNoContextCells,
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value()));
+ GET_VALUE(value, BuildLoadContextSlot(
+ context, depth, slot_index, ContextMode::kNoContextCells,
+ register_scope_infos_[iterator_.GetRegisterOperand(0)]));
SetAccumulator(value);
return ReduceResult::Done();
}
@@ -2986,7 +3008,7 @@ ReduceResult MaglevGraphBuilder::VisitStaContextSlotNoCell() {
return BuildStoreContextSlot(
context, depth, slot_index, GetAccumulator(),
ContextMode::kNoContextCells,
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value());
+ register_scope_infos_[iterator_.GetRegisterOperand(0)]);
}
ReduceResult MaglevGraphBuilder::VisitStaCurrentContextSlotNoCell() {
ValueNode* context = GetContext();
@@ -3003,7 +3025,7 @@ ReduceResult MaglevGraphBuilder::VisitStaContextSlot() {
return BuildStoreContextSlot(
context, depth, slot_index, GetAccumulator(),
ContextMode::kHasContextCells,
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value());
+ register_scope_infos_[iterator_.GetRegisterOperand(0)]);
}
ReduceResult MaglevGraphBuilder::VisitStaCurrentContextSlot() {
@@ -3447,7 +3469,7 @@ ReduceResult MaglevGraphBuilder::VisitLdaLookupContextSlot() {
}
bool MaglevGraphBuilder::CheckContextExtensions(size_t depth) {
- compiler::ScopeInfoRef scope_info = GetCurrentScopeInfo();
+ ContextScopeInfo scope_info = GetCurrentScopeInfo();
ValueNode* context = GetContext();
for (uint32_t d = 0; d < depth; d++) {
CHECK_NE(scope_info.scope_type(), ScopeType::SCRIPT_SCOPE);
@@ -4451,7 +4473,7 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildStoreField(
broker()->dependencies()->DependOnNoSlackTrackingChange(*original_map);
}
} else if (access_info.IsFastDataConstant() &&
- access_mode == compiler::AccessMode::kStore) {
+ access_mode != compiler::AccessMode::kStoreInLiteral) {
return reducer_.EmitUnconditionalDeopt(DeoptimizeReason::kStoreToConstant);
}
@@ -4709,7 +4731,7 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildNamedAccess(
bool has_deprecated_map_without_migration_target = false;
if (compiler::OptionalHeapObjectRef c =
TryGetConstant<HeapObject>(lookup_start_object)) {
- if (c.value().IsTheHole()) return {};
+ if (c.value().IsAnyHole()) return {};
if (c.value().IsJSFunctionWithPrototype() &&
feedback.name().equals(broker()->prototype_string())) {
compiler::JSFunctionRef function = c.value().AsJSFunction();
@@ -4750,9 +4772,9 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildNamedAccess(
{receiver, GetConstant(feedback.name()), GetAccumulator()},
feedback_source);
case compiler::AccessMode::kDefine:
+ case compiler::AccessMode::kStoreInLiteral:
return {};
case compiler::AccessMode::kHas:
- case compiler::AccessMode::kStoreInLiteral:
UNREACHABLE();
}
}
@@ -6677,7 +6699,7 @@ ReduceResult MaglevGraphBuilder::VisitLdaModuleVariable() {
// LdaModuleVariable <cell_index> <depth>
int cell_index = iterator_.GetImmediateOperand(0);
size_t depth = iterator_.GetUnsignedImmediateOperand(1);
- compiler::ScopeInfoRef scope_info = GetCurrentScopeInfo();
+ ContextScopeInfo scope_info = GetCurrentScopeInfo();
ValueNode* context = GetContextAtDepth(GetContext(), depth, &scope_info);
@@ -6709,8 +6731,9 @@ ReduceResult MaglevGraphBuilder::VisitLdaModuleVariable() {
return ReduceResult::Done();
}
-ValueNode* MaglevGraphBuilder::GetContextAtDepth(
- ValueNode* context, size_t depth, compiler::ScopeInfoRef* scope_info) {
+ValueNode* MaglevGraphBuilder::GetContextAtDepth(ValueNode* context,
+ size_t depth,
+ ContextScopeInfo* scope_info) {
MinimizeContextChainDepth(&context, &depth, scope_info);
compiler::OptionalContextRef maybe_ref =
@@ -6718,7 +6741,7 @@ ValueNode* MaglevGraphBuilder::GetContextAtDepth(
&depth);
if (maybe_ref.has_value()) {
context = GetConstant(maybe_ref.value());
- *scope_info = maybe_ref.value().scope_info(broker());
+ *scope_info = ContextScopeInfo(maybe_ref.value().scope_info(broker()));
}
for (size_t i = 0; i < depth; i++) {
@@ -6748,7 +6771,7 @@ ReduceResult MaglevGraphBuilder::VisitStaModuleVariable() {
}
size_t depth = iterator_.GetUnsignedImmediateOperand(1);
- compiler::ScopeInfoRef scope_info = GetCurrentScopeInfo();
+ ContextScopeInfo scope_info = GetCurrentScopeInfo();
ValueNode* context = GetContextAtDepth(GetContext(), depth, &scope_info);
@@ -6831,8 +6854,8 @@ ReduceResult MaglevGraphBuilder::VisitGetPrivateField() {
int slot_index = iterator_.GetContextSlotOperand(1);
size_t depth = iterator_.GetUnsignedImmediateOperand(2);
- compiler::ScopeInfoRef scope_info =
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value();
+ ContextScopeInfo scope_info =
+ register_scope_infos_[iterator_.GetRegisterOperand(0)];
ValueNode* context = GetContextAtDepth(current_context, depth, &scope_info);
VariableMode mode;
MaybeAssignedFlag assigned =
@@ -6891,8 +6914,8 @@ ReduceResult MaglevGraphBuilder::VisitSetPrivateField() {
int slot_index = iterator_.GetContextSlotOperand(1);
size_t depth = iterator_.GetUnsignedImmediateOperand(2);
- compiler::ScopeInfoRef scope_info =
- register_scope_infos_[iterator_.GetRegisterOperand(0)].value();
+ ContextScopeInfo scope_info =
+ register_scope_infos_[iterator_.GetRegisterOperand(0)];
ValueNode* context = GetContextAtDepth(current_context, depth, &scope_info);
VariableMode mode;
MaybeAssignedFlag assigned =
@@ -6952,6 +6975,16 @@ ReduceResult MaglevGraphBuilder::VisitSetPrototypeProperties() {
ReduceResult MaglevGraphBuilder::VisitDefineNamedOwnProperty() {
// DefineNamedOwnProperty <object> <name_index> <slot>
+ return VisitDefineNamedOwnPropertyHelper(false);
+}
+
+ReduceResult MaglevGraphBuilder::VisitDefineNamedOwnPropertyInLiteral() {
+ // DefineNamedOwnPropertyInLiteral <object> <name_index> <slot>
+ return VisitDefineNamedOwnPropertyHelper(true);
+}
+
+ReduceResult MaglevGraphBuilder::VisitDefineNamedOwnPropertyHelper(
+ bool in_literal) {
ValueNode* object = LoadRegister(0);
compiler::NameRef name = GetRefOperand<Name>(1);
FeedbackSlot slot = GetSlotOperand(2);
@@ -6975,7 +7008,9 @@ ReduceResult MaglevGraphBuilder::VisitDefineNamedOwnProperty() {
case compiler::ProcessedFeedback::kNamedAccess:
RETURN_IF_DONE(TryBuildNamedAccess(
object, object, processed_feedback.AsNamedAccess(), feedback_source,
- compiler::AccessMode::kDefine, build_generic_access));
+ in_literal ? compiler::AccessMode::kStoreInLiteral
+ : compiler::AccessMode::kDefine,
+ build_generic_access));
break;
default:
@@ -8375,10 +8410,18 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
ABORT_IF_EMPTY_TYPE(executing_constant);
ABORT_IF_EMPTY_TYPE(next_constant);
+ // The fast path below asks the generator to store the yielded value into
+ // yielded_value_ rather than allocate a result object, and rebuilds the
+ // object here as a VirtualObject that escape analysis can then elide. A
+ // current try-catch block, either in this function or in a caller we were
+ // inlined into, defeats that as would pay for the protocol and allocate
+ // anyway.
+ const bool can_skip_allocation = GetCurrentTryCatchBlock().ref == nullptr;
+
MaglevSubGraphBuilder::Label generator_already_closed(&subgraph, 1);
MaglevSubGraphBuilder::Label generator_finished(&subgraph, 1);
- MaglevSubGraphBuilder::Label allocation_not_skipped(&subgraph, 1);
- MaglevSubGraphBuilder::Label done(&subgraph, 4, {&ret_value});
+ MaglevSubGraphBuilder::Label done(&subgraph, can_skip_allocation ? 4 : 3,
+ {&ret_value});
RETURN_IF_ABORT(subgraph.GotoIfTrue<BranchIfReferenceEqual>(
&generator_already_closed, {continuation, closed_constant}));
@@ -8398,13 +8441,14 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
StoreTaggedMode::kDefault)
.IsDoneWithoutAbort());
- // Tell the generator to skip allocating the result object (if
- // possible).
- CHECK(BuildStoreTaggedFieldNoWriteBarrier(
- receiver, GetRootConstant(RootIndex::kTheHoleValue),
- offsetof(JSGeneratorObject, yielded_value_),
- StoreTaggedMode::kDefault)
- .IsDoneWithoutAbort());
+ // Tell the generator to skip allocating the result object if possible.
+ if (can_skip_allocation) {
+ CHECK(BuildStoreTaggedFieldNoWriteBarrier(
+ receiver, GetRootConstant(RootIndex::kTheHoleValue),
+ offsetof(JSGeneratorObject, yielded_value_),
+ StoreTaggedMode::kDefault)
+ .IsDoneWithoutAbort());
+ }
ValueNode* result;
{
@@ -8429,36 +8473,36 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
BuildLoadTaggedField(receiver,
offsetof(JSGeneratorObject, continuation_)));
- ValueNode* yielded_value;
- GET_VALUE(yielded_value,
- BuildLoadTaggedField(receiver,
- offsetof(JSGeneratorObject, yielded_value_)));
- // We unconditionally clear yielded_value_ here. If the generator did
- // not hit the GeneratorYieldResult intrinsic (if it suspended via
- // yield*), yielded_value_ would still hold TheHole. If it leaked to JS
- // space (e.g., on a subsequent unoptimized next() call), it could cause
- // a crash when JS attempts to access its properties.
- CHECK(BuildStoreTaggedFieldNoWriteBarrier(
- receiver, GetRootConstant(RootIndex::kUndefinedValue),
- offsetof(JSGeneratorObject, yielded_value_),
- StoreTaggedMode::kDefault)
- .IsDoneWithoutAbort());
-
CHECK(subgraph
.GotoIfTrue<BranchIfReferenceEqual>(
&generator_finished, {result_continuation, executing_constant})
.IsDoneWithoutAbort());
- // The generator is not yet finished.
- // Check whether skipping allocating the result object was successful.
- CHECK(subgraph
- .GotoIfFalse<BranchIfRootConstant>(
- &allocation_not_skipped, {result}, RootIndex::kTheHoleValue)
- .IsDoneWithoutAbort());
+ if (can_skip_allocation) {
+ MaglevSubGraphBuilder::Label allocation_not_skipped(&subgraph, 1);
+ ValueNode* yielded_value;
+ GET_VALUE(yielded_value,
+ BuildLoadTaggedField(
+ receiver, offsetof(JSGeneratorObject, yielded_value_)));
+ // We unconditionally clear yielded_value_ here. If the generator did
+ // not hit the GeneratorYieldResult intrinsic (if it suspended via
+ // yield*), yielded_value_ would still hold TheHole. If it leaked to JS
+ // space (e.g., on a subsequent unoptimized next() call), it could cause
+ // a crash when JS attempts to access its properties.
+ CHECK(BuildStoreTaggedFieldNoWriteBarrier(
+ receiver, GetRootConstant(RootIndex::kUndefinedValue),
+ offsetof(JSGeneratorObject, yielded_value_),
+ StoreTaggedMode::kDefault)
+ .IsDoneWithoutAbort());
- // Was able to avoid allocating the result object. Use
- // yielded_value from the generator object.
- {
+ // Check whether skipping allocating the result object was successful.
+ CHECK(subgraph
+ .GotoIfFalse<BranchIfRootConstant>(
+ &allocation_not_skipped, {result}, RootIndex::kTheHoleValue)
+ .IsDoneWithoutAbort());
+
+ // Was able to avoid allocating the result object. Use
+ // yielded_value from the generator object.
compiler::MapRef map =
broker()->target_native_context().iterator_result_map(broker());
VirtualObject* iter_result = reducer_.CreateJSIteratorResult(
@@ -8468,6 +8512,15 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
iter_result, AllocationType::kYoung));
subgraph.set(ret_value, alloc_result);
subgraph.Goto(&done);
+
+ subgraph.Bind(&allocation_not_skipped);
+
+ subgraph.set(ret_value, result);
+ subgraph.Goto(&done);
+ } else {
+ // The builtin allocated the result object for us.
+ subgraph.set(ret_value, result);
+ subgraph.Goto(&done);
}
subgraph.Bind(&generator_already_closed);
@@ -8508,14 +8561,6 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
subgraph.Goto(&done);
}
- subgraph.Bind(&allocation_not_skipped);
- {
- // Was not able to avoid allocating the result object; use
- // the result object as is.
- subgraph.set(ret_value, result);
- subgraph.Goto(&done);
- }
-
subgraph.Bind(&done);
return subgraph.get(ret_value);
}
@@ -10790,7 +10835,7 @@ MaglevGraphBuilder::GetArgumentsAsArrayOfValueNodes(
// TODO(victorgomes): Investigate if we can avoid this copy.
int arg_count = static_cast<int>(args.count());
auto arguments = zone()->AllocateVector<ValueNode*>(arg_count + 1);
- if (IsTheHoleConstant(args.receiver())) {
+ if (IsTdzHoleConstant(args.receiver())) {
arguments[0] = args.receiver();
} else {
ReduceResult result = GetConvertReceiver(shared, args);
@@ -10856,7 +10901,9 @@ ReduceResult MaglevGraphBuilder::BuildGenericCall(
MaybeReduceResult MaglevGraphBuilder::BuildCallSelf(
ValueNode* context, ValueNode* function, ValueNode* new_target,
compiler::SharedFunctionInfoRef shared, CallArguments& args) {
- if (IsTheHoleConstant(args.receiver())) return {};
+ if (IsTdzHoleConstant(args.receiver())) {
+ return {};
+ }
ValueNode* receiver;
GET_VALUE_OR_ABORT(receiver, GetConvertReceiver(shared, args));
size_t input_count = args.count() + CallSelf::kFixedInputCount;
@@ -10899,9 +10946,9 @@ bool MaglevGraphBuilder::TargetIsCurrentCompilingUnit(
MaybeReduceResult MaglevGraphBuilder::TryReduceCallForApiFunction(
compiler::FunctionTemplateInfoRef api_callback,
compiler::OptionalSharedFunctionInfoRef maybe_shared, CallArguments& args) {
- if (IsTheHoleConstant(args.receiver())) {
- // The receiver may be the_hole when inlining derived constructors and
- // construct_as_builtin constructors.
+ if (IsTdzHoleConstant(args.receiver())) {
+ // The receiver may be tdz_hole when inlining construct_as_builtin or
+ // derived constructors.
// TODO(jgruber): Support this case.
return {};
}
@@ -10961,7 +11008,7 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildCallKnownApiFunction(
return {};
}
- if (IsTheHoleConstant(args.receiver())) {
+ if (IsTdzHoleConstant(args.receiver())) {
// Not supported by CallFunctionTemplate.
return {};
}
@@ -11059,8 +11106,8 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildCallKnownApiFunction(
builtin_name, tagged_context);
}
-bool MaglevGraphBuilder::IsTheHoleConstant(ValueNode* node) {
- return reducer().IsTheHoleConstant(node);
+bool MaglevGraphBuilder::IsTdzHoleConstant(ValueNode* node) {
+ return reducer().IsTdzHoleConstant(node);
}
MaybeReduceResult MaglevGraphBuilder::TryBuildCallKnownJSFunction(
@@ -11093,8 +11140,8 @@ ReduceResult MaglevGraphBuilder::BuildCallKnownJSFunction(
compiler::FeedbackCellRef feedback_cell, CallArguments& args,
const compiler::FeedbackSource& feedback_source) {
ValueNode* receiver = args.receiver();
- if (!IsTheHoleConstant(receiver)) {
- // The receiver may be the_hole when inlining derived constructors and
+ if (!IsTdzHoleConstant(receiver)) {
+ // The receiver may be tdz_hole when inlining derived constructors and
// construct_as_builtin constructors. Only insert conversions when that is
// not the case.
GET_VALUE_OR_ABORT(receiver, GetConvertReceiver(shared, args));
@@ -12143,10 +12190,6 @@ ReduceResult MaglevGraphBuilder::VisitCallRuntime() {
{current_interpreter_frame_.get(args[0])}));
SetAccumulator(GetRootConstant(RootIndex::kUndefinedValue));
return ReduceResult::Done();
- case Runtime::kNewFunctionContext:
- accumulator_scope_info_ =
- compilation_unit_->shared_function_info().scope_info(broker());
- break;
default:
break;
}
@@ -12168,6 +12211,10 @@ ReduceResult MaglevGraphBuilder::VisitCallRuntime() {
},
function_id, context));
SetAccumulator(call_runtime);
+ if (function_id == Runtime::kNewFunctionContext) {
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(
+ compilation_unit_->shared_function_info().scope_info(broker()));
+ }
if (RuntimeFunctionWillThrow(function_id)) {
return reducer_.BuildAbort(AbortReason::kUnexpectedReturnFromThrow);
@@ -13108,7 +13155,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructBuiltin(
&reducer_, GetContext(),
Builtin::kStringCreateLazyDeoptContinuation, target_function,
base::VectorOf<ValueNode*>(
- {GetRootConstant(RootIndex::kTheHoleValue)}));
+ {GetRootConstant(RootIndex::kTdzHoleValue)}));
GET_VALUE_OR_ABORT(value,
BuildToString(args[0], ToString::kThrowOnSymbol));
}
@@ -13120,7 +13167,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructBuiltin(
break;
case Builtin::kTypedArrayConstructor: {
LazyDeoptFrameScope construct(
- &reducer_, GetContext(), GetRootConstant(RootIndex::kTheHoleValue),
+ &reducer_, GetContext(), GetRootConstant(RootIndex::kTdzHoleValue),
*compilation_unit(), GetCurrentSourcePosition());
RETURN_IF_DONE(reducer_.TryReduceTypedArrayConstructor(
GetContext(), target_function, new_target, args));
@@ -13147,7 +13194,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
const bool construct_as_builtin = shared_function_info.construct_as_builtin();
if (IsDerivedConstructor(shared_function_info.kind())) {
- ValueNode* implicit_receiver = GetRootConstant(RootIndex::kTheHoleValue);
+ ValueNode* implicit_receiver = GetRootConstant(RootIndex::kTdzHoleValue);
args.set_receiver(implicit_receiver);
ValueNode* call_result;
{
@@ -13180,7 +13227,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
ValueNode* implicit_receiver = nullptr;
if (construct_as_builtin) {
- implicit_receiver = GetRootConstant(RootIndex::kTheHoleValue);
+ implicit_receiver = GetRootConstant(RootIndex::kTdzHoleValue);
} else {
// We do not create a construct stub lazy deopt frame, since
// FastNewObject cannot fail if target is a JSFunction.
@@ -14351,7 +14398,7 @@ ReduceResult MaglevGraphBuilder::VisitCreateBlockContext() {
auto done = [&](ValueNode* res) {
SetAccumulator(res);
- accumulator_scope_info_ = scope_info;
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(scope_info);
};
PROCESS_AND_RETURN_IF_DONE(TryBuildInlinedAllocatedContext(
@@ -14376,7 +14423,7 @@ ReduceResult MaglevGraphBuilder::VisitCreateCatchContext() {
Context::MIN_CONTEXT_EXTENDED_SLOTS, scope_info, exception));
SetAccumulator(allocation);
- accumulator_scope_info_ = scope_info;
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(scope_info);
return ReduceResult::Done();
}
@@ -14388,7 +14435,7 @@ ReduceResult MaglevGraphBuilder::VisitCreateFunctionContext() {
auto done = [&](ValueNode* res) {
SetAccumulator(res);
- accumulator_scope_info_ = info;
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(info);
};
PROCESS_AND_RETURN_IF_DONE(
@@ -14413,7 +14460,7 @@ ReduceResult MaglevGraphBuilder::VisitCreateEvalContext() {
auto done = [&](ValueNode* res) {
SetAccumulator(res);
- accumulator_scope_info_ = info;
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(info);
};
PROCESS_AND_RETURN_IF_DONE(
@@ -14444,7 +14491,7 @@ ReduceResult MaglevGraphBuilder::VisitCreateWithContext() {
Context::MIN_CONTEXT_EXTENDED_SLOTS, scope_info, object));
SetAccumulator(allocation);
- accumulator_scope_info_ = scope_info;
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(scope_info);
return ReduceResult::Done();
}
@@ -14798,8 +14845,7 @@ void MaglevGraphBuilder::MergeIntoFrameState(BasicBlock* predecessor,
}
}
-void MaglevGraphBuilder::SetCurrentScopeInfo(
- compiler::OptionalScopeInfoRef scope_info) {
+void MaglevGraphBuilder::SetCurrentScopeInfo(ContextScopeInfo scope_info) {
if (v8_flags.trace_maglev_scope_info) {
int offset = iterator_.done() ? -1 : iterator_.current_offset();
if (scope_info.has_value()) {
@@ -15587,48 +15633,74 @@ ReduceResult MaglevGraphBuilder::VisitReturn() {
: ReduceResult::DoneWithAbort();
}
-ReduceResult MaglevGraphBuilder::VisitThrowReferenceErrorIfHole() {
- // ThrowReferenceErrorIfHole <variable_name>
+ReduceResult MaglevGraphBuilder::VisitThrowReferenceErrorIfTdzHole() {
+ // ThrowReferenceErrorIfTdzHole <variable_name>
compiler::NameRef name = GetRefOperand<Name>(0);
ValueNode* value = GetAccumulator();
- switch (value->IsTheHole()) {
+ switch (value->IsTdzHole()) {
case Tribool::kTrue:
return reducer_.EmitThrow(Throw::kThrowAccessedUninitializedVariable,
GetConstant(name));
case Tribool::kFalse:
return ReduceResult::Done();
- case Tribool::kMaybe:
+ case Tribool::kMaybe: {
DCHECK(value->is_tagged());
- return AddNewNode<ThrowReferenceErrorIfHole>({value}, name);
+ // Temporarily clear the cached constant value before emitting
+ // ThrowReferenceErrorIfTdzHole so that known_node_aspects() merged into
+ // the exception handler (the catch block) does not cache this load. On
+ // the exception path, the value is guaranteed to be tdz_hole, and the
+ // catch block may resume a generator that initializes the const variable.
+ // Restore the cached value afterward for the non-throwing fallthrough
+ // path where the value is known not to be tdz_hole.
+ // TODO(verwaest): Look into making loaded_context_constants_ monotonic,
+ // e.g. by folding the hole check into the context load rather than
+ // temporarily clearing the cached constant here.
+ ValueNode** cached_slot = nullptr;
+ if (auto* load = value->TryCast<LoadContextSlotNoCells>();
+ load && load->maybe_assigned() == kNotAssigned) {
+ ValueNode*& slot = known_node_aspects().GetContextCachedValue(
+ load->input(0).node(), load->offset(), kNotAssigned);
+ if (slot == value) {
+ cached_slot = &slot;
+ *cached_slot = nullptr;
+ }
+ }
+ ReduceResult res =
+ AddNewNode<ThrowReferenceErrorIfTdzHole>({value}, name);
+ if (cached_slot) {
+ *cached_slot = value;
+ }
+ return res;
+ }
}
UNREACHABLE();
}
-ReduceResult MaglevGraphBuilder::VisitThrowSuperNotCalledIfHole() {
- // ThrowSuperNotCalledIfHole
+ReduceResult MaglevGraphBuilder::VisitThrowSuperNotCalledIfTdzHole() {
+ // ThrowSuperNotCalledIfTdzHole
ValueNode* value = GetAccumulator();
if (CheckType(value, NodeType::kJSReceiver)) return ReduceResult::Done();
- switch (value->IsTheHole()) {
+ switch (value->IsTdzHole()) {
case Tribool::kTrue:
return reducer_.EmitThrow(Throw::kThrowSuperNotCalled);
case Tribool::kFalse:
return ReduceResult::Done();
case Tribool::kMaybe:
DCHECK(value->is_tagged());
- return AddNewNode<ThrowSuperNotCalledIfHole>({value});
+ return AddNewNode<ThrowSuperNotCalledIfTdzHole>({value});
}
UNREACHABLE();
}
-ReduceResult MaglevGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
- // ThrowSuperAlreadyCalledIfNotHole
+ReduceResult MaglevGraphBuilder::VisitThrowSuperAlreadyCalledIfNotTdzHole() {
+ // ThrowSuperAlreadyCalledIfNotTdzHole
ValueNode* value = GetAccumulator();
- switch (value->IsTheHole()) {
+ switch (value->IsTdzHole()) {
case Tribool::kTrue:
return ReduceResult::Done();
case Tribool::kFalse:
return reducer_.EmitThrow(Throw::kThrowSuperAlreadyCalledError);
case Tribool::kMaybe:
DCHECK(value->is_tagged());
- return AddNewNode<ThrowSuperAlreadyCalledIfNotHole>({value});
+ return AddNewNode<ThrowSuperAlreadyCalledIfNotTdzHole>({value});
}
UNREACHABLE();
}
@@ -16345,19 +16417,29 @@ ReduceResult MaglevGraphBuilder::VisitIllegal() { UNREACHABLE(); }
void MaglevGraphBuilder::InitializeScopeInfo() {
compiler::ScopeInfoRef scope_info =
compilation_unit_->shared_function_info().scope_info(broker());
+ bool has_incoming_context_scope = false;
if (scope_info.HasOuterScopeInfo()) {
scope_info = scope_info.OuterScopeInfo(broker());
CHECK(scope_info.HasContext());
- } else if (compilation_unit_->shared_function_info().is_toplevel()) {
- scope_info = compilation_unit_->shared_function_info().scope_info(broker());
+ has_incoming_context_scope = true;
+ } else if (compilation_unit_->shared_function_info().is_toplevel() &&
+ scope_info.HasContext()) {
+ has_incoming_context_scope = true;
}
- SetCurrentScopeInfo(scope_info);
+ std::optional<size_t> distance;
+ if (!is_inline() && has_incoming_context_scope &&
+ compilation_unit_->info()->specialization_context().has_value()) {
+ distance = compilation_unit_->info()->specialization_context_distance();
+ }
+ SetCurrentScopeInfo(ContextScopeInfo(scope_info, distance));
}
bool MaglevGraphBuilder::Build() {
DCHECK(!is_inline());
if (should_abort_compilation_) return false;
+ compilation_unit_->info()->InitializeSpecializationContext();
+
DCHECK_EQ(inlining_id_, SourcePosition::kNotInlined);
reducer_.SetBytecodeOffset(entrypoint_);
reducer_.SetStartSourcePosition(inlining_id_);
@@ -16423,19 +16505,21 @@ void MaglevGraphBuilder::PrewalkBytecode() {
case interpreter::Bytecode::kCreateEvalContext:
case interpreter::Bytecode::kCreateFunctionContextWithCells:
case interpreter::Bytecode::kCreateFunctionContext: {
- accumulator_scope_info_ = GetRefOperand<ScopeInfo>(0);
+ accumulator_scope_info_ =
+ GetCurrentScopeInfo().Push(GetRefOperand<ScopeInfo>(0));
break;
}
case interpreter::Bytecode::kCreateCatchContext:
case interpreter::Bytecode::kCreateWithContext: {
- accumulator_scope_info_ = GetRefOperand<ScopeInfo>(1);
+ accumulator_scope_info_ =
+ GetCurrentScopeInfo().Push(GetRefOperand<ScopeInfo>(1));
break;
}
case interpreter::Bytecode::kCallRuntime: {
uint16_t function_id = iterator_.GetRuntimeIdOperand(0);
if (function_id == Runtime::kNewFunctionContext) {
- accumulator_scope_info_ =
- compilation_unit_->shared_function_info().scope_info(broker());
+ accumulator_scope_info_ = GetCurrentScopeInfo().Push(
+ compilation_unit_->shared_function_info().scope_info(broker()));
}
break;
}
@@ -16483,12 +16567,12 @@ void MaglevGraphBuilder::OsrPrewalk() {
DCHECK_LT(context_index, registers_size);
struct OsrScopeState {
- base::Vector<compiler::OptionalScopeInfoRef> registers;
- compiler::OptionalScopeInfoRef accumulator;
+ base::Vector<ContextScopeInfo> registers;
+ ContextScopeInfo accumulator;
};
auto snapshot = [&]() -> OsrScopeState {
- base::Vector<compiler::OptionalScopeInfoRef> registers =
- zone()->AllocateVector<compiler::OptionalScopeInfoRef>(registers_size);
+ base::Vector<ContextScopeInfo> registers =
+ zone()->AllocateVector<ContextScopeInfo>(registers_size);
for (int i = first_register; i <= last_register; ++i) {
registers[i - first_register] =
register_scope_infos_[interpreter::Register(i)];
@@ -16521,7 +16605,7 @@ void MaglevGraphBuilder::OsrPrewalk() {
if (it == saved_states.end()) {
saved_states.emplace(target, state);
} else {
- DCHECK(context_scope_of(it->second).equals(context_scope_of(state)));
+ DCHECK_EQ(context_scope_of(it->second), context_scope_of(state));
}
};
@@ -16544,9 +16628,9 @@ void MaglevGraphBuilder::OsrPrewalk() {
auto it = saved_states.find(offset);
if (it != saved_states.end()) {
if (previous_fallsthrough) {
- DCHECK(context_scope_of(it->second)
- .equals(register_scope_infos_
- [interpreter::Register::current_context()]));
+ DCHECK_EQ(
+ context_scope_of(it->second),
+ register_scope_infos_[interpreter::Register::current_context()]);
} else {
restore(it->second);
}
@@ -16614,7 +16698,7 @@ void MaglevGraphBuilder::OsrPrewalk() {
for (auto& [offset, state] : saved_states) {
if (offset <= entrypoint_) continue;
if (offset >= bytecode_length) continue;
- compiler::OptionalScopeInfoRef scope = context_scope_of(state);
+ ContextScopeInfo scope = context_scope_of(state);
if (!scope.has_value()) continue;
if (merge_states_[offset] != nullptr) {
merge_states_[offset]->set_context_scope_info(scope);
diff --git a/deps/v8/src/maglev/maglev-graph-builder.h b/deps/v8/src/maglev/maglev-graph-builder.h
index b7daff41462..a439094bb6d 100644
--- a/deps/v8/src/maglev/maglev-graph-builder.h
+++ b/deps/v8/src/maglev/maglev-graph-builder.h
@@ -185,17 +185,17 @@ class MaglevGraphBuilder {
Graph* graph() const { return graph_; }
Zone* zone() const { return compilation_unit_->zone(); }
- compiler::ScopeInfoRef GetScopeInfo(interpreter::Register reg) const {
+ ContextScopeInfo GetScopeInfo(interpreter::Register reg) const {
auto opt_scope_info = register_scope_infos_[reg];
DCHECK(opt_scope_info.has_value());
- return opt_scope_info.value();
+ return opt_scope_info;
}
- compiler::ScopeInfoRef GetCurrentScopeInfo() const {
+ ContextScopeInfo GetCurrentScopeInfo() const {
return GetScopeInfo(interpreter::Register::current_context());
}
- void SetCurrentScopeInfo(compiler::OptionalScopeInfoRef scope_info);
+ void SetCurrentScopeInfo(ContextScopeInfo scope_info);
MaglevCompilationUnit* compilation_unit() const { return compilation_unit_; }
const InterpreterFrameState& current_interpreter_frame() const {
@@ -219,6 +219,8 @@ class MaglevGraphBuilder {
int inlining_depth() const { return compilation_unit_->inlining_depth(); }
DeoptFrame* GetLatestCheckpointedFrame();
+ // A checkpointed frame can always be built while the graph is being built.
+ bool CanEagerDeopt() const { return true; }
DeoptFrame* GetDeoptFrameForEagerDeopt() {
return GetLatestCheckpointedFrame();
}
@@ -408,7 +410,7 @@ class MaglevGraphBuilder {
}
ValueNode* GetContextAtDepth(ValueNode* context, size_t depth,
- compiler::ScopeInfoRef* out_scope_info);
+ ContextScopeInfo* out_scope_info);
bool CheckContextExtensions(size_t depth);
void KillPeeledLoopTargets(int peelings);
@@ -478,15 +480,15 @@ class MaglevGraphBuilder {
compiler::ScopeInfoRef scope_info);
ValueNode* TryGetParentContext(ValueNode* node);
void MinimizeContextChainDepth(ValueNode** context, size_t* depth,
- compiler::ScopeInfoRef* scope_info);
+ ContextScopeInfo* scope_info);
void EscapeContext();
ReduceResult BuildLoadContextSlot(ValueNode* context, size_t depth,
int slot_index, ContextMode context_mode,
- compiler::ScopeInfoRef scope_info);
+ ContextScopeInfo scope_info);
ReduceResult BuildStoreContextSlot(ValueNode* context, size_t depth,
int slot_index, ValueNode* value,
ContextMode context_mode,
- compiler::ScopeInfoRef scope_info);
+ ContextScopeInfo scope_info);
ReduceResult BuildExtendPropertiesBackingStore(compiler::MapRef map,
ValueNode* receiver,
ValueNode* property_array);
@@ -589,7 +591,7 @@ class MaglevGraphBuilder {
current_interpreter_frame_.set(dst, current_interpreter_frame_.get(src));
- compiler::OptionalScopeInfoRef src_scope_info;
+ ContextScopeInfo src_scope_info;
if (src == interpreter::Register::virtual_accumulator()) {
src_scope_info = accumulator_scope_info_;
} else {
@@ -1005,7 +1007,7 @@ class MaglevGraphBuilder {
MaybeReduceResult TryReduceAsyncFunctionResolve(
ValueNode* async_function_object, ValueNode* value);
bool TargetIsCurrentCompilingUnit(compiler::JSFunctionRef target);
- bool IsTheHoleConstant(ValueNode* node);
+ bool IsTdzHoleConstant(ValueNode* node);
ReduceResult BuildCallKnownJSFunction(
ValueNode* context, ValueNode* function, ValueNode* new_target,
JSDispatchHandle dispatch_handle, compiler::SharedFunctionInfoRef shared,
@@ -1361,6 +1363,7 @@ class MaglevGraphBuilder {
ReduceResult BuildGetKeyedProperty(
ValueNode* object, const compiler::FeedbackSource& feedback_source,
const compiler::ProcessedFeedback& processed_feedback);
+ ReduceResult VisitDefineNamedOwnPropertyHelper(bool in_literal);
ReduceResult BuildSetKeyedProperty(
ValueNode* object, ValueNode* index, compiler::AccessMode access_mode,
const compiler::FeedbackSource& feedback_source,
@@ -1931,8 +1934,8 @@ class MaglevGraphBuilder {
BasicBlockRef* jump_targets_;
MergePointInterpreterFrameState** merge_states_;
- RegisterFrameArray<compiler::OptionalScopeInfoRef> register_scope_infos_;
- compiler::OptionalScopeInfoRef accumulator_scope_info_;
+ RegisterFrameArray<ContextScopeInfo> register_scope_infos_;
+ ContextScopeInfo accumulator_scope_info_;
InterpreterFrameState current_interpreter_frame_;
@@ -1980,7 +1983,7 @@ class MaglevGraphBuilder {
ZoneUnorderedMap<KnownNodeAspects::LoadedContextSlotsKey, Node*>
unobserved_context_slot_stores_;
- ZoneMap<int, compiler::OptionalScopeInfoRef> dead_scope_infos_;
+ ZoneMap<int, ContextScopeInfo> dead_scope_infos_;
bool is_resumable_function_ = false;
diff --git a/deps/v8/src/maglev/maglev-graph-labeller.h b/deps/v8/src/maglev/maglev-graph-labeller.h
index 912249a2409..3d1046beeca 100644
--- a/deps/v8/src/maglev/maglev-graph-labeller.h
+++ b/deps/v8/src/maglev/maglev-graph-labeller.h
@@ -102,7 +102,7 @@ class MaglevGraphLabeller {
int next_node_label_ = 1;
};
-class MaglevGraphLabellerScope {
+class V8_EXPORT_PRIVATE MaglevGraphLabellerScope {
public:
explicit MaglevGraphLabellerScope(MaglevGraphLabeller* graph_labeller);
~MaglevGraphLabellerScope();
diff --git a/deps/v8/src/maglev/maglev-graph-optimizer.cc b/deps/v8/src/maglev/maglev-graph-optimizer.cc
index c4a40248555..8f5ec525e29 100644
--- a/deps/v8/src/maglev/maglev-graph-optimizer.cc
+++ b/deps/v8/src/maglev/maglev-graph-optimizer.cc
@@ -85,7 +85,7 @@ MaglevGraphOptimizer::GetDeoptFrameForLazyDeopt(bool can_throw) {
}
DeoptFrame* MaglevGraphOptimizer::GetDeoptFrameForEagerDeopt() {
- CHECK(current_node()->properties().has_eager_deopt_info());
+ CHECK(CanEagerDeopt());
DeoptFrame* frame = ¤t_node()->eager_deopt_info()->top_frame();
auto* eager_scope = reducer_.current_eager_deopt_scope();
@@ -524,9 +524,12 @@ void MaglevGraphOptimizer::PreProcessNode(Node* node,
}
void MaglevGraphOptimizer::PostProcessNode(Node* node) {
- if (node->opcode() != Opcode::kAllocationBlock &&
- (node->properties().can_allocate() || node->properties().can_deopt() ||
- node->properties().can_throw())) {
+ if (auto* allocation_block = node->TryCast<AllocationBlock>()) {
+ // This allocation is now the most recent young allocation, so it is the
+ // only block that subsequent allocations may be folded into.
+ reducer_.SetCurrentAllocationBlock(allocation_block);
+ } else if (node->properties().can_allocate() ||
+ node->properties().can_deopt() || node->properties().can_throw()) {
reducer_.ClearCurrentAllocationBlock();
}
#ifdef DEBUG
@@ -720,7 +723,7 @@ MaybeReduceResult MaglevGraphOptimizer::GetUntaggedValueWithRepresentation(
// TODO(victorgomes): The GetXXX functions may emit a conversion node that
// might eager deopt. We need to find a correct eager deopt frame for them if
// current_node_ does not have a deopt info.
- if (!current_node_->properties().has_eager_deopt_info()) {
+ if (!CanEagerDeopt()) {
return {};
}
switch (use_repr) {
@@ -1423,9 +1426,9 @@ ProcessResult MaglevGraphOptimizer::VisitReduceInterruptBudgetForReturn(
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitThrowReferenceErrorIfHole(
- ThrowReferenceErrorIfHole* node, const ProcessingState& state) {
- switch (node->ValueInput().node()->IsTheHole()) {
+ProcessResult MaglevGraphOptimizer::VisitThrowReferenceErrorIfTdzHole(
+ ThrowReferenceErrorIfTdzHole* node, const ProcessingState& state) {
+ switch (node->ValueInput().node()->IsTdzHole()) {
case Tribool::kTrue: {
return ThrowAndTruncate(Throw::kThrowAccessedUninitializedVariable,
reducer_.GetConstant(node->name()));
@@ -1439,9 +1442,9 @@ ProcessResult MaglevGraphOptimizer::VisitThrowReferenceErrorIfHole(
UNREACHABLE();
}
-ProcessResult MaglevGraphOptimizer::VisitThrowSuperNotCalledIfHole(
- ThrowSuperNotCalledIfHole* node, const ProcessingState& state) {
- switch (node->ValueInput().node()->IsTheHole()) {
+ProcessResult MaglevGraphOptimizer::VisitThrowSuperNotCalledIfTdzHole(
+ ThrowSuperNotCalledIfTdzHole* node, const ProcessingState& state) {
+ switch (node->ValueInput().node()->IsTdzHole()) {
case Tribool::kTrue: {
return ThrowAndTruncate(Throw::kThrowSuperNotCalled);
}
@@ -1454,9 +1457,9 @@ ProcessResult MaglevGraphOptimizer::VisitThrowSuperNotCalledIfHole(
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitThrowSuperAlreadyCalledIfNotHole(
- ThrowSuperAlreadyCalledIfNotHole* node, const ProcessingState& state) {
- switch (node->ValueInput().node()->IsTheHole()) {
+ProcessResult MaglevGraphOptimizer::VisitThrowSuperAlreadyCalledIfNotTdzHole(
+ ThrowSuperAlreadyCalledIfNotTdzHole* node, const ProcessingState& state) {
+ switch (node->ValueInput().node()->IsTdzHole()) {
case Tribool::kTrue:
// It is the hole; removing.
return RemoveCurrentNode();
@@ -2950,7 +2953,31 @@ ProcessResult MaglevGraphOptimizer::VisitNumberToString(
ProcessResult MaglevGraphOptimizer::VisitUpdateJSArrayLength(
UpdateJSArrayLength* node, const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
+ ValueNode* length = node->LengthInput().node();
+ ValueNode* index = node->IndexInput().node();
+
+ if (auto result = reducer_.TryFoldInt32Condition(
+ AssertCondition::kUnsignedLessThan, index, length)) {
+ if (result.value()) {
+ return ReplaceWith(length);
+ }
+ }
+
+ const auto r_index = GetRange(index);
+ const auto r_length = GetRange(length);
+ if (r_index && r_length) {
+ if (const auto result = TryFoldCompareWithRanges(
+ AssertCondition::kUnsignedLessThan, *r_index, *r_length)) {
+ if (result.value()) {
+ return ReplaceWith(length);
+ }
+ }
+ if (r_index->IsUint32() && r_length->IsUint32() &&
+ IsRangeLessEqual(index, length)) {
+ return ReplaceWith(length);
+ }
+ }
+
return ProcessResult::kContinue;
}
@@ -3650,7 +3677,7 @@ ProcessResult MaglevGraphOptimizer::VisitBranchIfToBooleanTrue(
// or a CheckNotHole before, which should have been constant-folded into
// unconditional deopt/throw if their input is a hole.
DCHECK_IMPLIES(node->input_node(0)->Is<HeapConstant>(),
- !node->input_node(0)->Cast<HeapConstant>()->IsTheHole());
+ !node->input_node(0)->Cast<HeapConstant>()->IsAnyHole());
bool condition =
FromConstantToBool(reducer_.local_isolate(), node->input_node(0));
diff --git a/deps/v8/src/maglev/maglev-graph-optimizer.h b/deps/v8/src/maglev/maglev-graph-optimizer.h
index 246d9716793..f41212a81ab 100644
--- a/deps/v8/src/maglev/maglev-graph-optimizer.h
+++ b/deps/v8/src/maglev/maglev-graph-optimizer.h
@@ -60,6 +60,11 @@ class V8_EXPORT_PRIVATE MaglevGraphOptimizer {
kna_processor_.set_known_node_aspects(known_node_aspects);
}
+ // GetDeoptFrameForEagerDeopt can only clone an existing eager deopt frame, so
+ // reductions of nodes that don't have one must not emit eager deopting nodes.
+ bool CanEagerDeopt() const {
+ return current_node_->properties().has_eager_deopt_info();
+ }
DeoptFrame* GetDeoptFrameForEagerDeopt();
std::tuple<DeoptFrame*, interpreter::Register, int> GetDeoptFrameForLazyDeopt(
diff --git a/deps/v8/src/maglev/maglev-graph.h b/deps/v8/src/maglev/maglev-graph.h
index d78d2fa4ad4..939d639b539 100644
--- a/deps/v8/src/maglev/maglev-graph.h
+++ b/deps/v8/src/maglev/maglev-graph.h
@@ -342,7 +342,7 @@ class Graph final : public ZoneObject {
constant.get_bits());
}
- HeapConstant* GetHeapNumberConstant(double constant);
+ V8_EXPORT_PRIVATE HeapConstant* GetHeapNumberConstant(double constant);
RootConstant* GetRootConstant(RootIndex index) {
return GetOrAddNewConstantNode(root_constants_, index);
diff --git a/deps/v8/src/maglev/maglev-interpreter-frame-state.cc b/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
index ed0d40bbbd7..fc4fa2ec83e 100644
--- a/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
+++ b/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
@@ -62,7 +62,7 @@ MergePointInterpreterFrameState* MergePointInterpreterFrameState::New(
const MaglevCompilationUnit& info, const InterpreterFrameState& state,
int merge_offset, int predecessor_count, BasicBlock* predecessor,
const compiler::BytecodeLivenessState* liveness,
- compiler::OptionalScopeInfoRef context_scope_info) {
+ ContextScopeInfo context_scope_info) {
MergePointInterpreterFrameState* merge_state =
info.zone()->New<MergePointInterpreterFrameState>(
info, merge_offset, predecessor_count, 1,
@@ -91,7 +91,7 @@ MergePointInterpreterFrameState* MergePointInterpreterFrameState::New(
}
void MergePointInterpreterFrameState::set_context_scope_info(
- compiler::OptionalScopeInfoRef scope_info) {
+ ContextScopeInfo scope_info) {
if (v8_flags.trace_maglev_scope_info) {
if (scope_info.has_value()) {
std::cout << " [ScopeInfo] set_context_scope_info: "
@@ -213,7 +213,7 @@ MergePointInterpreterFrameState::NewForCatchBlock(
const MaglevCompilationUnit& unit,
const compiler::BytecodeLivenessState* liveness, int handler_offset,
bool was_used, interpreter::Register context_register, Graph* graph,
- compiler::OptionalScopeInfoRef context_scope_info) {
+ ContextScopeInfo context_scope_info) {
Zone* const zone = unit.zone();
MergePointInterpreterFrameState* state =
zone->New<MergePointInterpreterFrameState>(
@@ -242,7 +242,7 @@ MergePointInterpreterFrameState::MergePointInterpreterFrameState(
const MaglevCompilationUnit& info, int merge_offset, int predecessor_count,
int predecessors_so_far, BasicBlock** predecessors, BasicBlockType type,
const compiler::BytecodeLivenessState* liveness,
- compiler::OptionalScopeInfoRef context_scope_info)
+ ContextScopeInfo context_scope_info)
: unit_(&info),
predecessor_count_(predecessor_count),
predecessors_so_far_(predecessors_so_far),
@@ -431,8 +431,8 @@ void MergePointInterpreterFrameState::MergeVirtualObjects(
void MergePointInterpreterFrameState::InitializeLoop(
Graph* graph, bool is_tracing, MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& unmerged, BasicBlock* predecessor,
- compiler::OptionalScopeInfoRef context_scope_info,
- bool optimistic_initial_state, LoopEffects* loop_effects) {
+ ContextScopeInfo context_scope_info, bool optimistic_initial_state,
+ LoopEffects* loop_effects) {
DCHECK(is_unmerged_loop());
context_scope_info_ = context_scope_info;
DCHECK_IMPLIES(optimistic_initial_state,
@@ -446,6 +446,7 @@ void MergePointInterpreterFrameState::InitializeLoop(
DCHECK_EQ(predecessors_so_far_, 0);
known_node_aspects_ = unmerged.known_node_aspects()->CloneForLoopHeader(
optimistic_initial_state, loop_effects, graph->zone());
+ AsLoopHeader()->InitializeLoopEffectEpoch(*known_node_aspects_);
unmerged.virtual_objects().Snapshot();
const MaglevCompilationInfo* info = compilation_unit.info();
TRACE(TraceColor::kInfo << "Initializing "
@@ -467,7 +468,7 @@ void MergePointInterpreterFrameState::InitializeWithBasicBlock(
void MergePointInterpreterFrameState::Merge(
Graph* graph, bool is_tracing, MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& unmerged, BasicBlock* predecessor,
- compiler::OptionalScopeInfoRef context_scope_info) {
+ ContextScopeInfo context_scope_info) {
DCHECK_GT(predecessor_count_, 1);
DCHECK_LT(predecessors_so_far_, predecessor_count_);
diff --git a/deps/v8/src/maglev/maglev-interpreter-frame-state.h b/deps/v8/src/maglev/maglev-interpreter-frame-state.h
index e6def7bf9b8..195569e6d70 100644
--- a/deps/v8/src/maglev/maglev-interpreter-frame-state.h
+++ b/deps/v8/src/maglev/maglev-interpreter-frame-state.h
@@ -32,6 +32,87 @@ class LoopMergePointInterpreterFrameState;
class MergePointInterpreterFrameState;
struct LoopEffects;
+// Bundles a static ScopeInfoRef with the distance (in Context::previous() hops)
+// from this scope to MaglevCompilationInfo::specialization_context().
+// - If specialization_context_distance() has a value, walking outward that many
+// steps reaches the specialization context.
+// - If specialization_context_distance() is std::nullopt (stored compactly as
+// kNoDistance to keep sizeof(ContextScopeInfo) == 16), either there is no
+// specialization context, this scope is inside an inlined compilation unit,
+// or we have walked outward past the specialization context.
+class ContextScopeInfo {
+ public:
+ ContextScopeInfo() = default;
+ ContextScopeInfo(std::nullopt_t) {} // NOLINT(runtime/explicit)
+ ContextScopeInfo(compiler::OptionalScopeInfoRef scope_info,
+ std::optional<size_t> specialization_context_distance =
+ std::nullopt) // NOLINT(runtime/explicit)
+ : scope_info_(scope_info),
+ specialization_context_distance_(
+ scope_info.has_value()
+ ? specialization_context_distance.value_or(kNoDistance)
+ : kNoDistance) {}
+
+ bool has_value() const { return scope_info_.has_value(); }
+ compiler::ScopeInfoRef value() const { return scope_info_.value(); }
+ operator compiler::ScopeInfoRef() const { return value(); }
+ compiler::OptionalScopeInfoRef scope_info() const { return scope_info_; }
+
+ bool HasOuterScopeInfo() const { return scope_info_->HasOuterScopeInfo(); }
+ bool HasContextExtensionSlot() const {
+ return scope_info_->HasContextExtensionSlot();
+ }
+ ScopeType scope_type() const { return scope_info_->scope_type(); }
+
+ std::optional<size_t> specialization_context_distance() const {
+ if (!has_value() || specialization_context_distance_ == kNoDistance) {
+ return std::nullopt;
+ }
+ return specialization_context_distance_;
+ }
+
+ V8_NODISCARD ContextScopeInfo Push(compiler::ScopeInfoRef inner_scope) const {
+ std::optional<size_t> inner_dist;
+ if (specialization_context_distance_ != kNoDistance) {
+ inner_dist = specialization_context_distance_ + 1;
+ }
+ return ContextScopeInfo(inner_scope, inner_dist);
+ }
+
+ V8_NODISCARD ContextScopeInfo
+ OuterScopeInfo(compiler::JSHeapBroker* broker) const {
+ DCHECK(has_value());
+ DCHECK(HasOuterScopeInfo());
+ std::optional<size_t> outer_dist;
+ if (specialization_context_distance_ != kNoDistance &&
+ specialization_context_distance_ > 0) {
+ outer_dist = specialization_context_distance_ - 1;
+ }
+ return ContextScopeInfo(scope_info_->OuterScopeInfo(broker), outer_dist);
+ }
+
+ bool operator==(const ContextScopeInfo& other) const {
+ DCHECK_IMPLIES(scope_info_.equals(other.scope_info_),
+ specialization_context_distance_ ==
+ other.specialization_context_distance_);
+ return scope_info_.equals(other.scope_info_);
+ }
+
+ friend std::ostream& operator<<(std::ostream& os,
+ const ContextScopeInfo& info) {
+ if (info.has_value()) {
+ return os << info.value();
+ }
+ return os << "<empty>";
+ }
+
+ private:
+ static constexpr size_t kNoDistance = std::numeric_limits<size_t>::max();
+
+ compiler::OptionalScopeInfoRef scope_info_;
+ size_t specialization_context_distance_ = kNoDistance;
+};
+
class InterpreterFrameState {
public:
InterpreterFrameState(const MaglevCompilationUnit& info,
@@ -301,7 +382,7 @@ class MergePointInterpreterFrameState {
const MaglevCompilationUnit& info, const InterpreterFrameState& state,
int merge_offset, int predecessor_count, BasicBlock* predecessor,
const compiler::BytecodeLivenessState* liveness,
- compiler::OptionalScopeInfoRef context_scope_info);
+ ContextScopeInfo context_scope_info);
static LoopMergePointInterpreterFrameState* NewForLoop(
const MaglevCompilationUnit& info, bool is_inline, Graph* graph,
@@ -313,31 +394,29 @@ class MergePointInterpreterFrameState {
const MaglevCompilationUnit& unit,
const compiler::BytecodeLivenessState* liveness, int handler_offset,
bool was_used, interpreter::Register context_register, Graph* graph,
- compiler::OptionalScopeInfoRef context_scope_info);
+ ContextScopeInfo context_scope_info);
static MergePointInterpreterFrameState* NewForPeel(
const MaglevCompilationUnit& info,
const MergePointInterpreterFrameState& template_state,
BasicBlock** predecessors, int predecessor_count);
- compiler::OptionalScopeInfoRef context_scope_info() const {
- return context_scope_info_;
- }
+ ContextScopeInfo context_scope_info() const { return context_scope_info_; }
bool has_context_scope_info() const {
return context_scope_info_.has_value();
}
- void set_context_scope_info(compiler::OptionalScopeInfoRef scope_info);
+ void set_context_scope_info(ContextScopeInfo scope_info);
// Merges an unmerged framestate with a possibly merged framestate into |this|
// framestate.
void Merge(Graph* graph, bool is_tracing,
MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& unmerged, BasicBlock* predecessor,
- compiler::OptionalScopeInfoRef context_scope_info);
+ ContextScopeInfo context_scope_info);
void InitializeLoop(Graph* graph, bool is_tracing,
MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& unmerged, BasicBlock* predecessor,
- compiler::OptionalScopeInfoRef context_scope_info,
+ ContextScopeInfo context_scope_info,
bool optimistic_initial_state = false,
LoopEffects* loop_effects = nullptr);
void InitializeWithBasicBlock(BasicBlock* current_block);
@@ -389,7 +468,7 @@ class MergePointInterpreterFrameState {
clear_is_loop();
}
- void RemovePredecessorAt(int predecessor_id);
+ V8_EXPORT_PRIVATE void RemovePredecessorAt(int predecessor_id);
// Returns and clears the known node aspects on this state. Expects to only
// ever be called once, when starting a basic block with this state.
@@ -413,6 +492,19 @@ class MergePointInterpreterFrameState {
}
}
+ // Adopts or merges `known_node_aspects`, and nulls it out to guarantee
+ // it is not reused by the caller.
+ void MergeNodeAspects(Zone* zone, KnownNodeAspects** known_node_aspects) {
+ DCHECK_NOT_NULL(known_node_aspects);
+ KnownNodeAspects* source = std::exchange(*known_node_aspects, nullptr);
+ DCHECK_NOT_NULL(source);
+ if (!known_node_aspects_) {
+ known_node_aspects_ = source;
+ } else {
+ known_node_aspects_->Merge(*source, zone);
+ }
+ }
+
const CompactInterpreterFrameState& frame_state() const {
return frame_state_;
}
@@ -550,7 +642,7 @@ class MergePointInterpreterFrameState {
const MaglevCompilationUnit& info, int merge_offset,
int predecessor_count, int predecessors_so_far, BasicBlock** predecessors,
BasicBlockType type, const compiler::BytecodeLivenessState* liveness,
- compiler::OptionalScopeInfoRef context_scope_info);
+ ContextScopeInfo context_scope_info);
void MergeLoopValue(Graph* graph, bool is_tracing,
interpreter::Register owner,
@@ -569,7 +661,7 @@ class MergePointInterpreterFrameState {
Alternatives::List* per_predecessor_alternatives,
bool optimistic_loop_phis = false);
- void ReducePhiPredecessorCount(unsigned num);
+ V8_EXPORT_PRIVATE void ReducePhiPredecessorCount(unsigned num);
void MergeVirtualObjects(Graph* graph, bool is_tracing,
const MaglevCompilationUnit& compilation_unit,
@@ -609,7 +701,7 @@ class MergePointInterpreterFrameState {
CompactInterpreterFrameState frame_state_;
KnownNodeAspects* known_node_aspects_ = nullptr;
- compiler::OptionalScopeInfoRef context_scope_info_;
+ ContextScopeInfo context_scope_info_;
union {
// {pre_predecessor_alternatives_} is used to keep track of the alternatives
@@ -651,6 +743,16 @@ class LoopMergePointInterpreterFrameState final
}
const LoopEffects* loop_effects() const { return loop_effects_; }
+ void InitializeLoopEffectEpoch(const KnownNodeAspects& aspects) {
+ loop_header_effect_epoch_ = aspects.effect_epoch_;
+ }
+ bool loop_has_effects() const {
+ return loop_header_effect_epoch_ ==
+ KnownNodeAspects::kEffectEpochOverflow ||
+ loop_header_effect_epoch_ !=
+ backedge_known_node_aspects()->effect_epoch_;
+ }
+
DeoptFrame* backedge_deopt_frame() const { return backedge_deopt_frame_; }
KnownNodeAspects* backedge_known_node_aspects() const {
@@ -674,6 +776,7 @@ class LoopMergePointInterpreterFrameState final
const LoopEffects* loop_effects_ = nullptr;
// The KNA from the backedge (end of the loop).
KnownNodeAspects* backedge_known_node_aspects_ = nullptr;
+ uint32_t loop_header_effect_epoch_ = KnownNodeAspects::kEffectEpochOverflow;
// The deopt frame for the backedge, in case we want to insert a deopting
// conversion during phi untagging. It is set when visiting the JumpLoop.
DeoptFrame* backedge_deopt_frame_ = nullptr;
@@ -694,8 +797,8 @@ MergePointInterpreterFrameState::AsLoopHeader() const {
#if V8_HOST_ARCH_64_BIT
// These asserts only exist to avoid accidentally bloating the merge states;
// the sizes can be increased if more fields are actually needed.
-static_assert(sizeof(MergePointInterpreterFrameState) == 96);
-static_assert(sizeof(LoopMergePointInterpreterFrameState) == 120);
+static_assert(sizeof(MergePointInterpreterFrameState) == 104);
+static_assert(sizeof(LoopMergePointInterpreterFrameState) == 136);
#endif
struct LoopEffects {
diff --git a/deps/v8/src/maglev/maglev-ir.cc b/deps/v8/src/maglev/maglev-ir.cc
index c25f1165cb3..499f75cb9a3 100644
--- a/deps/v8/src/maglev/maglev-ir.cc
+++ b/deps/v8/src/maglev/maglev-ir.cc
@@ -26,6 +26,7 @@
#include "src/compiler/js-heap-broker.h"
#include "src/deoptimizer/deoptimize-reason.h"
#include "src/execution/isolate-inl.h"
+#include "src/heap/heap-layout-inl.h"
#include "src/heap/local-heap.h"
#include "src/heap/parked-scope.h"
#include "src/interpreter/bytecode-flags-and-tokens.h"
@@ -836,10 +837,10 @@ Range ValueNode::GetStaticRange() const {
}
}
-Tribool ValueNode::IsTheHole() const {
- if (!CanBeTheHoleValue(opcode())) return Tribool::kFalse;
+Tribool ValueNode::IsHole(RootIndex hole_index) const {
+ if (!CanBeHoleValue(hole_index, opcode())) return Tribool::kFalse;
if (const RootConstant* cst = TryCast<RootConstant>()) {
- return ToTribool(cst->index() == RootIndex::kTheHoleValue);
+ return ToTribool(cst->index() == hole_index);
}
if (const LoadTaggedField* load = TryCast<LoadTaggedField>()) {
// There are a few ways that this can load a hole, for instance through a
@@ -854,19 +855,20 @@ Tribool ValueNode::IsTheHole() const {
return Tribool::kMaybe;
}
if (const LoadFixedArrayElement* load = TryCast<LoadFixedArrayElement>()) {
+ DCHECK_EQ(hole_index, RootIndex::kTheHoleValue);
if (load->load_type() != LoadType::kUnknown) {
return Tribool::kFalse;
}
return Tribool::kMaybe;
}
if (Is<Identity>()) {
- return UnwrapIdentities()->IsTheHole();
+ return UnwrapIdentities()->IsHole(hole_index);
}
if (const Phi* phi = TryCast<Phi>()) {
if (!phi->is_loop_phi() && !phi->is_exception_phi()) {
bool can_be_the_hole = false;
for (ConstInput input : phi->inputs()) {
- if (input.node()->IsTheHole() != Tribool::kFalse) {
+ if (input.node()->IsHole(hole_index) != Tribool::kFalse) {
can_be_the_hole = true;
break;
}
@@ -1041,13 +1043,16 @@ void CallBuiltin::MarkTaggedInputsAsDecompressing() {
void StoreTaggedFieldNoWriteBarrier::VerifyInputs() const {
Base::VerifyInputs();
- auto host_alloc = input(kObjectIndex).node()->TryCast<InlinedAllocation>();
- auto value_alloc = input(kValueIndex).node()->TryCast<InlinedAllocation>();
- if (host_alloc && value_alloc &&
- host_alloc->allocation_block() == value_alloc->allocation_block()) {
- CHECK_EQ(host_alloc->allocation_block()->allocation_type(),
- AllocationType::kYoung);
- }
+ // Here we'd like to verify that the write barrier can legitimately be
+ // skipped. However, we cannot, since this might be in dead code and our
+ // information might be inconsistent. This is because: 1) in Turbolev, we
+ // occasionally run the verifier before running GraphOptimizer which would
+ // delete dead branches and 2) we generally cannot detect upfront when we're
+ // in dead code.
+
+ // TODO(562805652): Could run the check for pure maglev (non-turbolev)
+ // compilations without eager inlining, if we were able to have that info
+ // here.
}
void InlinedAllocation::VerifyInputs() const {
@@ -1113,6 +1118,22 @@ void AllocationBlock::TryPretenure(ValueNode* value) {
}
}
+StoreMap::StoreMap(uint64_t bitfield, compiler::MapRef map, Kind kind)
+ : Base(bitfield | KindField::encode(kind) |
+ MapInReadOnlySpaceField::encode(
+ HeapLayout::InReadOnlySpace(*map.object()))),
+ map_(map) {}
+
+bool StoreMap::NoWriteBarrier() const {
+ if (MapInReadOnlySpaceField::decode(bitfield())) return true;
+ return kind() == Kind::kInlinedAllocation &&
+ ValueInput()
+ .node()
+ ->Cast<InlinedAllocation>()
+ ->allocation_block()
+ ->allocation_type() == AllocationType::kYoung;
+}
+
// ---
// Reify constants
// ---
@@ -1273,11 +1294,19 @@ void HoleyFloat64Constant::DoLoadToRegister(MaglevAssembler* masm,
}
void HeapConstant::DoLoadToRegister(MaglevAssembler* masm, Register reg) const {
- __ Move(reg, object_.object());
+ if (decompresses_tagged_result()) {
+ __ Move(reg, object_.object());
+ } else {
+ __ MoveTagged(reg, object_.object());
+ }
}
void RootConstant::DoLoadToRegister(MaglevAssembler* masm, Register reg) const {
- __ LoadRoot(reg, index());
+ if (decompresses_tagged_result()) {
+ __ LoadRoot(reg, index());
+ } else {
+ __ LoadTaggedRoot(reg, index());
+ }
}
void TrustedConstant::DoLoadToRegister(MaglevAssembler* masm,
@@ -3735,43 +3764,45 @@ void StoreFixedDoubleArrayHole::GenerateCode(MaglevAssembler* masm,
}
int StoreMap::MaxCallStackArgs() const {
- return WriteBarrierDescriptor::GetStackParameterCount();
+ return NoWriteBarrier() ? 0
+ : WriteBarrierDescriptor::GetStackParameterCount();
}
void StoreMap::SetValueLocationConstraints() {
- UseFixed(ValueInput(), WriteBarrierDescriptor::ObjectRegister());
- set_temporaries_needed(1);
+ if (NoWriteBarrier()) {
+ UseRegister(ValueInput());
+ if (!MaglevAssembler::kSupportsStoreTaggedConstant) {
+ set_temporaries_needed(1);
+ }
+ } else {
+ UseFixed(ValueInput(), WriteBarrierDescriptor::ObjectRegister());
+ set_temporaries_needed(1);
+ }
}
void StoreMap::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
MaglevAssembler::TemporaryRegisterScope temps(masm);
- // TODO(leszeks): Consider making this an arbitrary register and push/popping
- // in the deferred path.
- Register object = WriteBarrierDescriptor::ObjectRegister();
- DCHECK_EQ(object, ToRegister(ValueInput()));
- Register value = temps.Acquire();
- __ MoveTagged(value, map_.object());
-
- switch (kind()) {
- case Kind::kInlinedAllocation: {
- DCHECK(ValueInput().node()->Cast<InlinedAllocation>());
- auto inlined = ValueInput().node()->Cast<InlinedAllocation>();
- if (inlined->allocation_block()->allocation_type() ==
- AllocationType::kYoung) {
- __ StoreTaggedFieldNoWriteBarrier(object, offsetof(HeapObject, map_),
- value);
- __ AssertElidedWriteBarrier(object, value, register_snapshot());
- break;
- }
- [[fallthrough]];
+ Register object = ToRegister(ValueInput());
+ if (NoWriteBarrier()) {
+ if (MaglevAssembler::kSupportsStoreTaggedConstant) {
+ __ StoreTaggedFieldNoWriteBarrier(object, offsetof(HeapObject, map_),
+ map_.object());
+ __ AssertElidedWriteBarrier(object, map_, register_snapshot());
+ } else {
+ Register value = temps.Acquire();
+ __ MoveTagged(value, map_.object());
+ __ StoreTaggedFieldNoWriteBarrier(object, offsetof(HeapObject, map_),
+ value);
+ __ AssertElidedWriteBarrier(object, value, register_snapshot());
}
- case Kind::kInitializing:
- case Kind::kTransitioning:
- __ StoreTaggedFieldWithWriteBarrier(object, offsetof(HeapObject, map_),
- value, register_snapshot(),
- MaglevAssembler::kValueIsCompressed,
- MaglevAssembler::kValueCannotBeSmi);
- break;
+ return;
}
+
+ DCHECK_EQ(object, WriteBarrierDescriptor::ObjectRegister());
+ Register value = temps.Acquire();
+ __ MoveTagged(value, map_.object());
+ __ StoreTaggedFieldWithWriteBarrier(
+ object, offsetof(HeapObject, map_), value, register_snapshot(),
+ MaglevAssembler::kValueIsCompressed, MaglevAssembler::kValueCannotBeSmi);
}
int StoreTaggedFieldWithWriteBarrier::MaxCallStackArgs() const {
@@ -6075,30 +6106,75 @@ void StoreFloat64::GenerateCode(MaglevAssembler* masm,
__ StoreFloat64(FieldMemOperand(object, offset()), value);
}
+namespace {
+
+// The 32 bits that {StoreInt32} writes for a constant value input, i.e. the
+// low 32 bits of what loading the constant into a register would produce.
+// Inlined allocations pass Smi constants unconverted for raw fields that hold
+// a Smi-encoded length.
+std::optional<int32_t> TryGetInt32ConstantForStoring(ValueNode* value) {
+ switch (value->opcode()) {
+ case Opcode::kInt32Constant:
+ return value->Cast<Int32Constant>()->value();
+ case Opcode::kUint32Constant:
+ return static_cast<int32_t>(value->Cast<Uint32Constant>()->value());
+ case Opcode::kSmiConstant:
+ return static_cast<int32_t>(
+ static_cast<intptr_t>(value->Cast<SmiConstant>()->value().ptr()));
+ default:
+ return {};
+ }
+}
+
+} // namespace
+
void StoreInt32::SetValueLocationConstraints() {
UseRegister(ObjectInput());
- UseRegister(ValueInput());
+ if (TryGetInt32ConstantForStoring(ValueInput().node())) {
+ // Stored as an immediate, so no register is needed for the value.
+ UseAny(ValueInput());
+ } else {
+ UseRegister(ValueInput());
+ }
}
void StoreInt32::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register object = ToRegister(ObjectInput());
- Register value = ToRegister(ValueInput());
__ AssertNotSmi(object);
+ if (ValueInput().operand().IsConstant()) {
+ __ StoreInt32Field(object, offset(),
+ *TryGetInt32ConstantForStoring(ValueInput().node()));
+ return;
+ }
+ Register value = ToRegister(ValueInput());
__ StoreInt32(FieldMemOperand(object, offset()), value);
}
void StoreTaggedFieldNoWriteBarrier::SetValueLocationConstraints() {
UseRegister(ObjectInput());
- UseRegister(ValueInput());
+ if (MaglevAssembler::CanStoreTaggedConstant(ValueInput().node())) {
+ // The constant is stored as an immediate and needs no register.
+ UseAny(ValueInput());
+ } else {
+ UseRegister(ValueInput());
+ }
}
void StoreTaggedFieldNoWriteBarrier::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
Register object = ToRegister(ObjectInput());
- Register value = ToRegister(ValueInput());
__ AssertNotSmi(object);
+ if (ValueInput().operand().IsConstant()) {
+ ValueNode* constant = ValueInput().node();
+ DCHECK(MaglevAssembler::CanStoreTaggedConstant(constant));
+ __ StoreTaggedFieldNoWriteBarrier(object, offset(), constant);
+ __ AssertElidedWriteBarrier(object, constant, register_snapshot());
+ return;
+ }
+
+ Register value = ToRegister(ValueInput());
__ StoreTaggedFieldNoWriteBarrier(object, offset(), value);
__ AssertElidedWriteBarrier(object, value, register_snapshot());
}
@@ -6747,8 +6823,8 @@ void Float64ToString::GenerateCode(MaglevAssembler* masm,
masm->DefineLazyDeoptPoint(this->lazy_deopt_info());
}
-int ThrowReferenceErrorIfHole::MaxCallStackArgs() const { return 1; }
-void ThrowReferenceErrorIfHole::SetValueLocationConstraints() {
+int ThrowReferenceErrorIfTdzHole::MaxCallStackArgs() const { return 1; }
+void ThrowReferenceErrorIfTdzHole::SetValueLocationConstraints() {
// MaglevAssembler::IsRootConstant (used in GenerateCode below) does not
// support constant inputs (which UseAny allows). Constants should have been
// optimized already by MaglevGraphBuilder or MaglevGraphOptimizer.
@@ -6756,11 +6832,18 @@ void ThrowReferenceErrorIfHole::SetValueLocationConstraints() {
UseAny(ValueInput());
}
-void ThrowReferenceErrorIfHole::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
+void ThrowReferenceErrorIfTdzHole::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ if (v8_flags.debug_code) {
+ __ Assert(NegateCondition(
+ __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue)),
+ AbortReason::kUnexpectedValue);
+ }
+#endif
__ JumpToDeferredIf(
- __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue),
- [](MaglevAssembler* masm, ThrowReferenceErrorIfHole* node) {
+ __ IsRootConstant(ValueInput(), RootIndex::kTdzHoleValue),
+ [](MaglevAssembler* masm, ThrowReferenceErrorIfTdzHole* node) {
__ Push(node->name().object());
__ Move(kContextRegister, masm->native_context().object());
__ CallRuntime(Runtime::kThrowAccessedUninitializedVariable, 1);
@@ -6770,8 +6853,8 @@ void ThrowReferenceErrorIfHole::GenerateCode(MaglevAssembler* masm,
this);
}
-int ThrowSuperNotCalledIfHole::MaxCallStackArgs() const { return 0; }
-void ThrowSuperNotCalledIfHole::SetValueLocationConstraints() {
+int ThrowSuperNotCalledIfTdzHole::MaxCallStackArgs() const { return 0; }
+void ThrowSuperNotCalledIfTdzHole::SetValueLocationConstraints() {
// MaglevAssembler::IsRootConstant (used in GenerateCode below) does not
// support constant inputs (which UseAny allows). Constants should have been
// optimized already by MaglevGraphBuilder or MaglevGraphOptimizer.
@@ -6779,11 +6862,18 @@ void ThrowSuperNotCalledIfHole::SetValueLocationConstraints() {
UseAny(ValueInput());
}
-void ThrowSuperNotCalledIfHole::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
+void ThrowSuperNotCalledIfTdzHole::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ if (v8_flags.debug_code) {
+ __ Assert(NegateCondition(
+ __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue)),
+ AbortReason::kUnexpectedValue);
+ }
+#endif
__ JumpToDeferredIf(
- __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue),
- [](MaglevAssembler* masm, ThrowSuperNotCalledIfHole* node) {
+ __ IsRootConstant(ValueInput(), RootIndex::kTdzHoleValue),
+ [](MaglevAssembler* masm, ThrowSuperNotCalledIfTdzHole* node) {
__ Move(kContextRegister, masm->native_context().object());
__ CallRuntime(Runtime::kThrowSuperNotCalled, 0);
masm->DefineExceptionHandlerAndLazyDeoptPoint(node);
@@ -6792,8 +6882,8 @@ void ThrowSuperNotCalledIfHole::GenerateCode(MaglevAssembler* masm,
this);
}
-int ThrowSuperAlreadyCalledIfNotHole::MaxCallStackArgs() const { return 0; }
-void ThrowSuperAlreadyCalledIfNotHole::SetValueLocationConstraints() {
+int ThrowSuperAlreadyCalledIfNotTdzHole::MaxCallStackArgs() const { return 0; }
+void ThrowSuperAlreadyCalledIfNotTdzHole::SetValueLocationConstraints() {
// MaglevAssembler::IsRootConstant (used in GenerateCode below) does not
// support constant inputs (which UseAny allows). Constants should have been
// optimized already by MaglevGraphBuilder or MaglevGraphOptimizer.
@@ -6801,12 +6891,19 @@ void ThrowSuperAlreadyCalledIfNotHole::SetValueLocationConstraints() {
UseAny(ValueInput());
}
-void ThrowSuperAlreadyCalledIfNotHole::GenerateCode(
+void ThrowSuperAlreadyCalledIfNotTdzHole::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ if (v8_flags.debug_code) {
+ __ Assert(NegateCondition(
+ __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue)),
+ AbortReason::kUnexpectedValue);
+ }
+#endif
__ JumpToDeferredIf(
NegateCondition(
- __ IsRootConstant(ValueInput(), RootIndex::kTheHoleValue)),
- [](MaglevAssembler* masm, ThrowSuperAlreadyCalledIfNotHole* node) {
+ __ IsRootConstant(ValueInput(), RootIndex::kTdzHoleValue)),
+ [](MaglevAssembler* masm, ThrowSuperAlreadyCalledIfNotTdzHole* node) {
__ Move(kContextRegister, masm->native_context().object());
__ CallRuntime(Runtime::kThrowSuperAlreadyCalledError, 0);
masm->DefineExceptionHandlerAndLazyDeoptPoint(node);
diff --git a/deps/v8/src/maglev/maglev-ir.h b/deps/v8/src/maglev/maglev-ir.h
index f81191933fb..c9adf3113ae 100644
--- a/deps/v8/src/maglev/maglev-ir.h
+++ b/deps/v8/src/maglev/maglev-ir.h
@@ -491,9 +491,9 @@ class ExceptionHandlerInfo;
V(HandleNoHeapWritesInterrupt) \
V(ReduceInterruptBudgetForLoop) \
V(ReduceInterruptBudgetForReturn) \
- V(ThrowReferenceErrorIfHole) \
- V(ThrowSuperNotCalledIfHole) \
- V(ThrowSuperAlreadyCalledIfNotHole) \
+ V(ThrowReferenceErrorIfTdzHole) \
+ V(ThrowSuperNotCalledIfTdzHole) \
+ V(ThrowSuperAlreadyCalledIfNotTdzHole) \
V(ThrowIfNotCallable) \
V(ThrowIfNotSuperConstructor) \
V(TransitionElementsKindOrCheckMap) \
@@ -787,22 +787,26 @@ constexpr bool CanBeStoreToNonEscapedObject(Opcode opcode) {
}
}
-constexpr bool CanBeTheHoleValue(Opcode opcode) {
+constexpr bool CanBeHoleValue(RootIndex hole_index, Opcode opcode) {
+ DCHECK(hole_index == RootIndex::kTheHoleValue ||
+ hole_index == RootIndex::kTdzHoleValue);
switch (opcode) {
// TODO(victorgomes): Should we have a list of builtins that could
// return the hole?
case Opcode::kCallBuiltin:
- case Opcode::kCallRuntime:
- case Opcode::kGeneratorRestoreRegister:
case Opcode::kIdentity:
- case Opcode::kInitialValue:
- case Opcode::kLoadContextSlot:
- case Opcode::kLoadContextSlotNoCells:
- case Opcode::kLoadFixedArrayElement:
case Opcode::kLoadTaggedField:
case Opcode::kPhi:
case Opcode::kRootConstant:
return true;
+ case Opcode::kCallRuntime:
+ case Opcode::kLoadFixedArrayElement:
+ return hole_index == RootIndex::kTheHoleValue;
+ case Opcode::kGeneratorRestoreRegister:
+ case Opcode::kInitialValue:
+ case Opcode::kLoadContextSlot:
+ case Opcode::kLoadContextSlotNoCells:
+ return hole_index == RootIndex::kTdzHoleValue;
default:
return false;
}
@@ -1767,8 +1771,8 @@ inline compiler::BytecodeArrayRef DeoptFrame::GetBytecodeArray() const {
class DeoptInfo {
protected:
- DeoptInfo(Zone* zone, DeoptFrame* top_frame,
- compiler::FeedbackSource feedback_to_update);
+ V8_EXPORT_PRIVATE DeoptInfo(Zone* zone, DeoptFrame* top_frame,
+ compiler::FeedbackSource feedback_to_update);
public:
DeoptFrame& top_frame() { return *top_frame_; }
@@ -2720,7 +2724,7 @@ class ValueNode : public Node {
// HoleyFloat64 gives a meaning to. Only false if that is provably not the
// case, so that whoever writes those bits somewhere they would regain that
// meaning (a double array, mainly) can skip canonicalizing them.
- bool MayBeHoleOrUndefinedNan() const;
+ V8_EXPORT_PRIVATE bool MayBeHoleOrUndefinedNan() const;
#ifdef V8_COMPRESS_POINTERS
constexpr bool decompresses_tagged_result() const {
@@ -2783,14 +2787,16 @@ class ValueNode : public Node {
compiler::OptionalHeapObjectRef TryGetConstant(
compiler::JSHeapBroker* broker);
- NodeType GetStaticType(compiler::JSHeapBroker* broker);
- Range GetStaticRange() const;
+ V8_EXPORT_PRIVATE NodeType GetStaticType(compiler::JSHeapBroker* broker);
+ V8_EXPORT_PRIVATE Range GetStaticRange() const;
bool StaticTypeIs(compiler::JSHeapBroker* broker, NodeType type) {
return NodeTypeIs(GetStaticType(broker), type);
}
- Tribool IsTheHole() const;
+ Tribool IsHole(RootIndex hole_index) const;
+ Tribool IsTheHole() const { return IsHole(RootIndex::kTheHoleValue); }
+ Tribool IsTdzHole() const { return IsHole(RootIndex::kTdzHoleValue); }
inline void MaybeRecordUseReprHint(UseRepresentationSet repr);
inline void MaybeRecordUseReprHint(UseRepresentation repr);
@@ -4845,7 +4851,15 @@ class TestInstanceOf : public FixedInputValueNodeT<3, TestInstanceOf> {
: Base(bitfield), feedback_(feedback) {}
// The implementation currently calls runtime.
- static constexpr OpProperties kProperties = OpProperties::JSCall();
+ // Eager deopt frame is attached, since MaglevGraphOptimizer can reduce this
+ // node, and the reduction emits map checks, which can eager deopt.
+ // Unlike generic call nodes like CallBuiltin where attaching eager deopt
+ // frames would be too heavyweight (and are instead handled via
+ // MaglevReducer::CanEagerDeopt), TestInstanceOf is a dedicated opcode where
+ // attaching the frame is cheap and preserves speculative reductions in the
+ // optimizer.
+ static constexpr OpProperties kProperties =
+ OpProperties::EagerDeopt() | OpProperties::JSCall();
DECLARE_INPUTS(Context, Object, Callable)
DECLARE_INPUT_TYPES(Tagged, Tagged, Tagged)
@@ -5287,7 +5301,9 @@ class HeapConstant : public FixedInputValueNodeT<0, HeapConstant> {
return Object::BooleanValue(*object_.object(), local_isolate);
}
+ bool IsAnyHole() const { return object_.IsAnyHole(); }
bool IsTheHole() const { return object_.IsTheHole(); }
+ bool IsTdzHole() const { return object_.IsTdzHole(); }
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
@@ -9343,8 +9359,7 @@ class StoreMap : public FixedInputNodeT<1, StoreMap> {
kInlinedAllocation,
kTransitioning,
};
- explicit StoreMap(uint64_t bitfield, compiler::MapRef map, Kind kind)
- : Base(bitfield | KindField::encode(kind)), map_(map) {}
+ explicit StoreMap(uint64_t bitfield, compiler::MapRef map, Kind kind);
static constexpr OpProperties kProperties =
OpProperties::CanWrite() | OpProperties::DeferredCall();
@@ -9352,6 +9367,7 @@ class StoreMap : public FixedInputNodeT<1, StoreMap> {
compiler::MapRef map() const { return map_; }
Kind kind() const { return KindField::decode(bitfield()); }
+ bool NoWriteBarrier() const;
bool is_transitioning() const {
switch (kind()) {
@@ -9371,6 +9387,7 @@ class StoreMap : public FixedInputNodeT<1, StoreMap> {
private:
using KindField = NextBitField<Kind, 3>;
+ using MapInReadOnlySpaceField = KindField::Next<bool, 1>;
const compiler::MapRef map_;
};
std::ostream& operator<<(std::ostream& os, StoreMap::Kind);
@@ -10174,8 +10191,8 @@ class Phi : public ValueNodeT<Phi> {
// Records a use hint for this Phi. If {force_same_loop} is true, the hint
// is recorded as a same-loop use, which is important for loop-related
// optimizations like Phi untagging.
- void RecordUseReprHint(UseRepresentationSet repr_mask,
- bool force_same_loop = false);
+ V8_EXPORT_PRIVATE void RecordUseReprHint(UseRepresentationSet repr_mask,
+ bool force_same_loop = false);
UseRepresentationSet use_repr_hints() { return use_repr_hints_; }
UseRepresentationSet same_loop_use_repr_hints() {
@@ -10759,6 +10776,7 @@ class CallKnownJSFunction : public VarargsValueNodeT<4, CallKnownJSFunction> {
OpProperties::JSCall() | OpProperties::DeferredCall();
DECLARE_INPUTS(Target, Context, Receiver, NewTarget)
+ JSDispatchHandle dispatch_handle() const { return dispatch_handle_; }
compiler::SharedFunctionInfoRef shared_function_info() const {
return shared_function_info_;
}
@@ -11177,11 +11195,11 @@ class ReduceInterruptBudgetForReturn
const int amount_;
};
-class ThrowReferenceErrorIfHole
- : public FixedInputNodeT<1, ThrowReferenceErrorIfHole> {
+class ThrowReferenceErrorIfTdzHole
+ : public FixedInputNodeT<1, ThrowReferenceErrorIfTdzHole> {
public:
- explicit ThrowReferenceErrorIfHole(uint64_t bitfield,
- const compiler::NameRef name)
+ explicit ThrowReferenceErrorIfTdzHole(uint64_t bitfield,
+ const compiler::NameRef name)
: Base(bitfield), name_(name) {}
static constexpr OpProperties kProperties =
@@ -11200,10 +11218,10 @@ class ThrowReferenceErrorIfHole
const compiler::NameRef name_;
};
-class ThrowSuperNotCalledIfHole
- : public FixedInputNodeT<1, ThrowSuperNotCalledIfHole> {
+class ThrowSuperNotCalledIfTdzHole
+ : public FixedInputNodeT<1, ThrowSuperNotCalledIfTdzHole> {
public:
- explicit ThrowSuperNotCalledIfHole(uint64_t bitfield) : Base(bitfield) {}
+ explicit ThrowSuperNotCalledIfTdzHole(uint64_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties =
OpProperties::CanThrow() | OpProperties::DeferredCall();
@@ -11214,10 +11232,10 @@ class ThrowSuperNotCalledIfHole
void GenerateCode(MaglevAssembler*, const ProcessingState&);
};
-class ThrowSuperAlreadyCalledIfNotHole
- : public FixedInputNodeT<1, ThrowSuperAlreadyCalledIfNotHole> {
+class ThrowSuperAlreadyCalledIfNotTdzHole
+ : public FixedInputNodeT<1, ThrowSuperAlreadyCalledIfNotTdzHole> {
public:
- explicit ThrowSuperAlreadyCalledIfNotHole(uint64_t bitfield)
+ explicit ThrowSuperAlreadyCalledIfNotTdzHole(uint64_t bitfield)
: Base(bitfield) {}
static constexpr OpProperties kProperties =
diff --git a/deps/v8/src/maglev/maglev-kna-processor.h b/deps/v8/src/maglev/maglev-kna-processor.h
index 1965a9de1fb..a94b4266082 100644
--- a/deps/v8/src/maglev/maglev-kna-processor.h
+++ b/deps/v8/src/maglev/maglev-kna-processor.h
@@ -70,11 +70,22 @@ class RecomputeKnownNodeAspectsProcessor {
NodeBase* current_node() const { return current_node_; }
+ bool CanEagerDeopt() const {
+ return current_node()->properties().has_eager_deopt_info();
+ }
+
DeoptFrame* GetDeoptFrameForEagerDeopt() {
- CHECK(current_node()->properties().has_eager_deopt_info());
+ CHECK(CanEagerDeopt());
return ¤t_node()->eager_deopt_info()->top_frame();
}
+ static BasicBlock* SkipEdgeSplits(BasicBlock* block) {
+ while (block->is_edge_split_block()) {
+ block = block->control_node()->Cast<Jump>()->target();
+ }
+ return block;
+ }
+
BlockProcessResult PreProcessBasicBlock(BasicBlock* block) {
// TODO(victorgomes): Clean up set_current_block usage; now both
// MaglevGraphOptimizer and RecomputeKnownNodeAspectsProcessor set it.
@@ -98,16 +109,14 @@ class RecomputeKnownNodeAspectsProcessor {
backedge_known_node_aspects->UnwrapIdentitiesAndPhisInKeys(zone());
known_node_aspects_->MergeForLoop(
*backedge_known_node_aspects, zone(),
- block->state()->AsLoopHeader()->loop_effects());
+ block->state()->AsLoopHeader()->loop_effects(),
+ block->state()->AsLoopHeader()->loop_has_effects());
} else if (block->has_state()) {
known_node_aspects_ = block->state()->TakeKnownNodeAspects();
} else if (block->is_edge_split_block()) {
// Clone the next available KNA.
- BasicBlock* next_block = block;
- while (next_block->is_edge_split_block()) {
- next_block = next_block->control_node()->Cast<Jump>()->target();
- }
- known_node_aspects_ = next_block->state()->CloneKnownNodeAspects(zone());
+ known_node_aspects_ =
+ SkipEdgeSplits(block)->state()->CloneKnownNodeAspects(zone());
} else {
is_fallthrough = true;
}
@@ -168,7 +177,33 @@ class RecomputeKnownNodeAspectsProcessor {
if (mark_handler_reachable) {
tracker_.MarkReachable(exception_handler);
}
+ // Temporarily clear the cached constant value before merging into the
+ // exception handler so that the catch block does not cache this load. On
+ // the exception path, the value is guaranteed to be the_hole, and the
+ // catch block may resume a generator that initializes the variable.
+ // Restore the cached value afterward for the non-throwing fallthrough
+ // path where the value is known not to be the_hole.
+ // TODO(verwaest): Look into making loaded_context_constants_ monotonic,
+ // e.g. by folding the hole check into the context load rather than
+ // temporarily clearing the cached constant here.
+ ValueNode** cached_slot = nullptr;
+ ValueNode* value = nullptr;
+ if (auto* throw_if_hole = node->TryCast<ThrowReferenceErrorIfTdzHole>()) {
+ value = throw_if_hole->ValueInput().node();
+ if (auto* load = value->TryCast<LoadContextSlotNoCells>();
+ load && load->maybe_assigned() == kNotAssigned) {
+ ValueNode*& slot = known_node_aspects().GetContextCachedValue(
+ load->input(0).node(), load->offset(), kNotAssigned);
+ if (slot == value) {
+ cached_slot = &slot;
+ *cached_slot = nullptr;
+ }
+ }
+ }
Merge(exception_handler);
+ if (cached_slot) {
+ *cached_slot = value;
+ }
}
}
@@ -199,12 +234,12 @@ class RecomputeKnownNodeAspectsProcessor {
}
ProcessResult Process(Jump* node, const ProcessingState& state) {
- Merge(node->target());
+ MergeFromDeadSource(node->target());
return ProcessResult::kContinue;
}
ProcessResult Process(CheckpointedJump* node, const ProcessingState& state) {
- Merge(node->target());
+ MergeFromDeadSource(node->target());
return ProcessResult::kContinue;
}
@@ -272,14 +307,20 @@ class RecomputeKnownNodeAspectsProcessor {
V8_NODISCARD ProcessResult OnContradiction();
void Merge(BasicBlock* block) {
- while (block->is_edge_split_block()) {
- block = block->control_node()->Cast<Jump>()->target();
- }
+ block = SkipEdgeSplits(block);
// If we don't have state, this must be a fallthrough basic block.
if (!block->has_state()) return;
block->state()->MergeNodeAspects(zone(), *known_node_aspects_);
}
+ // Like Merge, but consume known_node_aspects_ instead of copying it.
+ void MergeFromDeadSource(BasicBlock* block) {
+ block = SkipEdgeSplits(block);
+ // If we don't have state, this must be a fallthrough basic block.
+ if (!block->has_state()) return;
+ block->state()->MergeNodeAspects(zone(), &known_node_aspects_);
+ }
+
template <typename NodeT>
void MarkPossibleSideEffect(NodeT* node) {
known_node_aspects().MarkPossibleSideEffect(node, broker(),
diff --git a/deps/v8/src/maglev/maglev-known-node-aspects.cc b/deps/v8/src/maglev/maglev-known-node-aspects.cc
index 8234a646671..f4abfca2495 100644
--- a/deps/v8/src/maglev/maglev-known-node-aspects.cc
+++ b/deps/v8/src/maglev/maglev-known-node-aspects.cc
@@ -393,8 +393,8 @@ void KnownNodeAspects::Merge(const KnownNodeAspects& other, Zone* zone) {
// loop-invariant values the peeler cloned), invalidating only what the loop
// body can change.
void KnownNodeAspects::MergeForLoop(const KnownNodeAspects& backedge,
- Zone* zone,
- const LoopEffects* loop_effects) {
+ Zone* zone, const LoopEffects* loop_effects,
+ bool loop_has_effects) {
if (side_effects_require_invalidation_ &&
(loop_effects == nullptr || loop_effects->unstable_aspects_cleared ||
loop_effects->elements_kind_transitioned)) {
@@ -407,45 +407,23 @@ void KnownNodeAspects::MergeForLoop(const KnownNodeAspects& backedge,
side_effects_require_invalidation_ = false;
}
- if (effect_epoch_ != backedge.effect_epoch_) {
- effect_epoch_ = std::max(effect_epoch_, backedge.effect_epoch_) + 1;
- }
- // Forward entries for pure (epoch-exempt) expressions are kept even without
- // a backedge equivalent: the forward predecessor dominates the loop body and
- // loop effects cannot invalidate a pure expression. Other entries need a
- // structurally equal backedge entry with a still-valid epoch.
- for (auto it = available_expressions_.begin();
- it != available_expressions_.end();) {
- const AvailableExpression& lhs = it->second;
- DCHECK_NE(lhs.effect_epoch, kEffectEpochOverflow);
- DCHECK_IMPLIES(!lhs.node->Is<Identity>(),
- Node::needs_epoch_check(lhs.node->opcode()) ==
- (lhs.effect_epoch != kEffectEpochForPureInstructions));
- if (lhs.node->Is<Identity>()) {
- it = available_expressions_.erase(it);
- continue;
- }
- if (lhs.effect_epoch == kEffectEpochForPureInstructions) {
- ++it;
- continue;
- }
- bool keep = false;
- auto rhs_it = backedge.available_expressions_.find(it->first);
- if (rhs_it != backedge.available_expressions_.end()) {
- const AvailableExpression& rhs = rhs_it->second;
- DCHECK_IMPLIES(lhs.node == rhs.node,
- lhs.effect_epoch == rhs.effect_epoch);
- ValueNode* rhs_value = rhs.node->TryCast<ValueNode>();
- NodeBase* rhs_node = rhs_value ? rhs_value->UnwrapIdentities() : rhs.node;
- keep = lhs.node->IsStructurallyEqualTo(rhs_node) &&
- lhs.effect_epoch >= effect_epoch_;
- }
- if (keep) {
- ++it;
- } else {
- it = available_expressions_.erase(it);
- }
- }
+ // TODO(jgruber): Recompute loop effects after lazy inlining, which can
+ // replace effectful calls with pure operations.
+ if (loop_has_effects) increment_effect_epoch();
+
+ std::erase_if(available_expressions_, [&](const auto& entry) {
+ const AvailableExpression& expr = entry.second;
+ DCHECK_NE(expr.effect_epoch, kEffectEpochOverflow);
+ DCHECK_IMPLIES(!expr.node->Is<Identity>(),
+ Node::needs_epoch_check(expr.node->opcode()) ==
+ (expr.effect_epoch != kEffectEpochForPureInstructions));
+ if (expr.node->Is<Identity>()) return true;
+ if (expr.effect_epoch == kEffectEpochForPureInstructions) return false;
+ // The graph builder's backedge epoch is not comparable with the recomputed
+ // forward epoch. loop_has_effects was determined during graph building.
+ if (loop_has_effects) return true;
+ return expr.effect_epoch < effect_epoch_;
+ });
const bool keep_invariant_loads =
loop_effects != nullptr && !loop_effects->unstable_aspects_cleared;
@@ -992,6 +970,17 @@ bool KnownNodeAspects::SetContextCachedValue(ValueNode* context, int offset,
ValueNode* value,
MaybeAssignedFlag assigned) {
value = value->UnwrapIdentities();
+ if (assigned == kNotAssigned) {
+ if (auto* root_const = value->TryCast<RootConstant>()) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK_NE(root_const->index(), RootIndex::kTheHoleValue);
+#endif
+ if (root_const->index() == RootIndex::kTdzHoleValue) {
+ loaded_context_constants_.erase({context, offset});
+ return false;
+ }
+ }
+ }
auto& target_map = (assigned == kMaybeAssigned) ? loaded_context_slots_
: loaded_context_constants_;
diff --git a/deps/v8/src/maglev/maglev-known-node-aspects.h b/deps/v8/src/maglev/maglev-known-node-aspects.h
index 3534466cdd1..b7f03911366 100644
--- a/deps/v8/src/maglev/maglev-known-node-aspects.h
+++ b/deps/v8/src/maglev/maglev-known-node-aspects.h
@@ -563,8 +563,10 @@ class KnownNodeAspects {
}
void Merge(const KnownNodeAspects& other, Zone* zone);
- void MergeForLoop(const KnownNodeAspects& backedge, Zone* zone,
- const LoopEffects* loop_effects);
+ V8_EXPORT_PRIVATE void MergeForLoop(const KnownNodeAspects& backedge,
+ Zone* zone,
+ const LoopEffects* loop_effects,
+ bool loop_has_effects);
// If IsCompatibleWithLoopHeader(other) returns true, it means that
// Merge(other) would not remove any information from `this`.
diff --git a/deps/v8/src/maglev/maglev-phi-representation-selector.h b/deps/v8/src/maglev/maglev-phi-representation-selector.h
index 47556c1a4bb..5ecca6b95f2 100644
--- a/deps/v8/src/maglev/maglev-phi-representation-selector.h
+++ b/deps/v8/src/maglev/maglev-phi-representation-selector.h
@@ -95,8 +95,10 @@ class MaglevPhiRepresentationSelector {
return UpdateNodeInputs(node, &state);
}
+ bool CanEagerDeopt() const { return eager_deopt_frame_ != nullptr; }
+
DeoptFrame* GetDeoptFrameForEagerDeopt() {
- DCHECK_NOT_NULL(eager_deopt_frame_);
+ DCHECK(CanEagerDeopt());
return eager_deopt_frame_;
}
diff --git a/deps/v8/src/maglev/maglev-range.h b/deps/v8/src/maglev/maglev-range.h
index dbd6e4ec6f7..20abc8a4894 100644
--- a/deps/v8/src/maglev/maglev-range.h
+++ b/deps/v8/src/maglev/maglev-range.h
@@ -193,6 +193,13 @@ class Range {
static Range Mul(Range r1, Range r2) {
if (r1.is_empty() || r2.is_empty()) return Range::Empty();
if (r1.is_all() || r2.is_all()) return Range::All();
+
+ // Multiplication by infinity can produce NaN if the other operand can be 0.
+ if (((r1.min_ == kInfMin || r1.max_ == kInfMax) && r2.contains(0)) ||
+ ((r2.min_ == kInfMin || r2.max_ == kInfMax) && r1.contains(0))) {
+ return Range::All();
+ }
+
int64_t results[4];
if (base::bits::SignedMulOverflow64(r1.min_, r2.min_, &results[0])) {
return Range::All();
diff --git a/deps/v8/src/maglev/maglev-reducer-inl.h b/deps/v8/src/maglev/maglev-reducer-inl.h
index 2bfe98dbf1d..41371336573 100644
--- a/deps/v8/src/maglev/maglev-reducer-inl.h
+++ b/deps/v8/src/maglev/maglev-reducer-inl.h
@@ -716,6 +716,11 @@ MaybeAssignedFlag MaglevReducer<BaseT>::GetContextMaybeAssigned(
}
int header_length = scope_info.ContextHeaderLength();
if (index < header_length) {
+ DCHECK_EQ(index, Context::EXTENSION_INDEX);
+ if (scope_info.SloppyEvalCanExtendVars()) {
+ *mode = VariableMode::kVar;
+ return kMaybeAssigned;
+ }
*mode = VariableMode::kConst;
return kNotAssigned;
}
@@ -2758,6 +2763,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
access_info.lookup_start_object_maps(), kStartAtPrototype);
if (callable_node_if_not_constant) {
+ if (!CanEagerDeopt()) return {};
RETURN_IF_ABORT(BuildCheckMaps(
callable_node_if_not_constant,
base::VectorOf(access_info.lookup_start_object_maps())));
@@ -2765,6 +2771,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
if (receiver_map.is_stable()) {
broker()->dependencies()->DependOnStableMap(receiver_map);
} else {
+ if (!CanEagerDeopt()) return {};
RETURN_IF_ABORT(BuildCheckMaps(
GetConstant(callable),
base::VectorOf(access_info.lookup_start_object_maps())));
@@ -2813,6 +2820,11 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
callable_node = GetConstant(callable);
}
+ // If we reach this point, then we've passed the
+ // ReducerBaseCanBuildCall<BaseT> check, which only holds for the
+ // GraphBuilder, for which CanEagerDeopt is true, which means that we can
+ // emit a CheckMaps.
+ DCHECK(CanEagerDeopt());
RETURN_IF_ABORT(BuildCheckMaps(
callable_node, base::VectorOf(access_info.lookup_start_object_maps())));
@@ -3380,19 +3392,15 @@ CallBuiltin* MaglevReducer<BaseT>::BuildCallBuiltin(
// LINT.IfChange(WasmWrapperInliningConditions)
template <typename BaseT>
bool MaglevReducer<BaseT>::ShouldWrapArgsForWasmInlining(
- compiler::SharedFunctionInfoRef shared, JSDispatchHandle dispatch_handle) {
+ JSDispatchHandle dispatch_handle) {
if (!is_turbolev()) return false;
if (!v8_flags.wasm_in_js_inlining_wrapper) return false;
- // The SharedFunctionInfo of a Wasm exported function does not carry a
- // builtin ID, so the check below filters out regular JS builtins.
- // However, the Code installed in the dispatch table can be either:
+ // The Code installed in the dispatch table for a Wasm exported function can
+ // be either:
// - The generic kJSToWasmWrapper builtin (used before a per-signature
// wrapper has been compiled), or
// - A jitted per-signature wrapper (CodeKind::JS_TO_WASM_FUNCTION).
- // We detect both cases by inspecting the Code object directly.
- if (!shared.object()->HasWasmExportedFunctionData(local_isolate())) {
- return false;
- }
+ // We detect both cases by inspecting the Code object via the dispatch table.
Tagged<Code> code =
local_isolate()->js_dispatch_table().GetCode(dispatch_handle);
return code->builtin_id() == Builtin::kJSToWasmWrapper ||
@@ -3410,7 +3418,7 @@ ReduceResult MaglevReducer<BaseT>::BuildCallKnownJSFunction(
compiler::FeedbackSource const& feedback_source) {
#if V8_ENABLE_WEBASSEMBLY
const bool wrap_args_for_wasm =
- ShouldWrapArgsForWasmInlining(shared, dispatch_handle);
+ ShouldWrapArgsForWasmInlining(dispatch_handle);
#endif // V8_ENABLE_WEBASSEMBLY
size_t input_count = arg_count + CallKnownJSFunction::kFixedInputCount;
@@ -3683,6 +3691,13 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldInt32BinaryOperation(
if (base::bits::SignedMulOverflow32(cst_left, cst_right, &result)) {
return {};
}
+ // The product is -0 if it is zero and either operand is negative (the
+ // other is then +0). -0 is not representable as an Int32 constant, so
+ // bail out and let Int32MultiplyWithOverflow handle it, as the -x fold
+ // above does.
+ if (result == 0 && (cst_left < 0 || cst_right < 0)) {
+ return {};
+ }
return GetInt32Constant(result);
case Operation::kModulus:
// TODO(v8:7700): Constant fold mod.
@@ -4196,11 +4211,11 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldTestTypeOf(
}
template <typename BaseT>
-bool MaglevReducer<BaseT>::IsTheHoleConstant(ValueNode* node) {
+bool MaglevReducer<BaseT>::IsTdzHoleConstant(ValueNode* node) {
if (node != nullptr) {
if (compiler::OptionalHeapObjectRef maybe_constant =
TryGetConstant<HeapObject>(node)) {
- return maybe_constant->IsTheHole();
+ return maybe_constant->IsTdzHole();
}
}
return false;
@@ -4210,7 +4225,7 @@ template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::GetConvertReceiver(
compiler::SharedFunctionInfoRef shared, ValueNode* receiver,
ConvertReceiverMode mode) {
- DCHECK(!IsTheHoleConstant(receiver));
+ DCHECK(!IsTdzHoleConstant(receiver));
if (shared.native() || shared.language_mode() == LanguageMode::kStrict) {
if (mode == ConvertReceiverMode::kNullOrUndefined) {
return GetRootConstant(RootIndex::kUndefinedValue);
@@ -6544,7 +6559,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceTypedArrayConstructor(
LazyDeoptFrameScope continuation(
this, context, Builtin::kGenericLazyDeoptContinuation, target,
base::VectorOf<ValueNode* const>(
- {GetRootConstant(RootIndex::kTheHoleValue)}));
+ {GetRootConstant(RootIndex::kTdzHoleValue)}));
return BuildCallBuiltinWithTaggedInputs<Builtin::kCreateTypedArray>(
GetConstant(broker()->target_native_context()),
{target_node, new_target, arg0, arg1, arg2});
diff --git a/deps/v8/src/maglev/maglev-reducer.h b/deps/v8/src/maglev/maglev-reducer.h
index 7320e7c18a6..ef286e3e6b1 100644
--- a/deps/v8/src/maglev/maglev-reducer.h
+++ b/deps/v8/src/maglev/maglev-reducer.h
@@ -304,9 +304,13 @@ concept ReducerBaseWithKNASetter = requires(BaseT* b, KnownNodeAspects* kna) {
b->set_known_node_aspects(kna);
};
+// Bases that can emit eager deopting nodes provide both an eager deopt frame
+// and a predicate telling whether one is available at the current position.
template <typename BaseT>
-concept ReducerBaseWithEagerDeopt =
- requires(BaseT* b) { b->GetDeoptFrameForEagerDeopt(); };
+concept ReducerBaseWithEagerDeopt = requires(BaseT* b) {
+ b->GetDeoptFrameForEagerDeopt();
+ b->CanEagerDeopt();
+};
template <typename BaseT>
concept ReducerBaseWithAbruptBlockEnd =
@@ -746,6 +750,20 @@ class MaglevReducer {
return current_eager_deopt_scope_;
}
+ // Whether an eager deopt frame is available at the current position, ie,
+ // whether a reduction is allowed to emit nodes that can eager deopt. This is
+ // always the case while building the graph, but not while optimizing it: a
+ // node that only has lazy deopt info has no eager deopt frame to clone, and
+ // its lazy deopt frame cannot be used instead, since that one describes the
+ // state *after* the bytecode rather than the state needed to re-execute it.
+ bool CanEagerDeopt() const {
+ if constexpr (ReducerBaseWithEagerDeopt<BaseT>) {
+ return base_->CanEagerDeopt();
+ } else {
+ return false;
+ }
+ }
+
MaglevReducer(BaseT* base, Graph* graph,
MaglevCompilationUnit* compilation_unit = nullptr)
: base_(base),
@@ -965,8 +983,7 @@ class MaglevReducer {
compiler::FeedbackSource const& feedback_source);
#if V8_ENABLE_WEBASSEMBLY
- bool ShouldWrapArgsForWasmInlining(compiler::SharedFunctionInfoRef shared,
- JSDispatchHandle dispatch_handle);
+ bool ShouldWrapArgsForWasmInlining(JSDispatchHandle dispatch_handle);
#endif // V8_ENABLE_WEBASSEMBLY
compiler::OptionalStringRef GetStringFromInt32(int32_t value);
@@ -1063,6 +1080,9 @@ class MaglevReducer {
ReduceResult BuildAndAllocateJSArrayIterator(ValueNode* array,
IterationKind iteration_kind);
void ClearCurrentAllocationBlock();
+ void SetCurrentAllocationBlock(AllocationBlock* block) {
+ current_allocation_block_ = block;
+ }
void AddNonEscapingUses(InlinedAllocation* allocation, int use_count);
AllocationBlock* current_allocation_block() const {
return current_allocation_block_;
@@ -1545,7 +1565,7 @@ class MaglevReducer {
ValueNode* GetNumberConstant(double constant);
- bool IsTheHoleConstant(ValueNode* node);
+ bool IsTdzHoleConstant(ValueNode* node);
ReduceResult GetConvertReceiver(compiler::SharedFunctionInfoRef shared,
ValueNode* receiver,
ConvertReceiverMode mode);
diff --git a/deps/v8/src/maglev/maglev-register-frame-array.h b/deps/v8/src/maglev/maglev-register-frame-array.h
index 311bf8b06af..43f09a6775e 100644
--- a/deps/v8/src/maglev/maglev-register-frame-array.h
+++ b/deps/v8/src/maglev/maglev-register-frame-array.h
@@ -29,9 +29,10 @@ class RegisterFrameArray {
static_assert(interpreter::Register(0).index() == 0);
constexpr int frame_size_between_params_and_locals = -first_param.index();
- T* frame = info.zone()->AllocateArray<T>(
- info.parameter_count() + frame_size_between_params_and_locals +
- info.register_count());
+ int size = info.parameter_count() + frame_size_between_params_and_locals +
+ info.register_count();
+ T* frame = info.zone()->AllocateArray<T>(size);
+ std::uninitialized_fill_n(frame, size, T{});
// Set frame_start_ to a "butterfly" pointer into the middle of the above
// Zone-allocated array, so that locals start at zero.
diff --git a/deps/v8/src/maglev/maglev-truncation.h b/deps/v8/src/maglev/maglev-truncation.h
index ff7c82b2b6c..c78aabc4280 100644
--- a/deps/v8/src/maglev/maglev-truncation.h
+++ b/deps/v8/src/maglev/maglev-truncation.h
@@ -471,9 +471,12 @@ class TruncationProcessor {
return ProcessResult::kContinue;
}
+ bool CanEagerDeopt() const {
+ return current_node()->properties().has_eager_deopt_info();
+ }
+
DeoptFrame* GetDeoptFrameForEagerDeopt() {
- DCHECK(current_node()->properties().can_eager_deopt() ||
- current_node()->properties().is_deopt_checkpoint());
+ DCHECK(CanEagerDeopt());
return ¤t_node()->eager_deopt_info()->top_frame();
}
diff --git a/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h b/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h
index a14e55d0bdc..3b8afc64a8a 100644
--- a/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h
+++ b/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h
@@ -337,7 +337,7 @@ inline void MaglevAssembler::BuildTypedArrayDataPointer(Register data_pointer,
inline MemOperand MaglevAssembler::TypedArrayElementOperand(
Register data_pointer, Register index, int element_size) {
TemporaryRegisterScope temps(this);
- Register temp = r0;
+ Register temp = temps.AcquireScratch();
ShiftLeftU64(temp, index, Operand(ShiftFromScale(element_size)));
AddS64(data_pointer, data_pointer, temp);
return MemOperand(data_pointer);
@@ -486,7 +486,7 @@ inline void MaglevAssembler::SetSlotAddressForTaggedField(Register slot_reg,
inline void MaglevAssembler::SetSlotAddressForFixedArrayElement(
Register slot_reg, Register object, Register index) {
TemporaryRegisterScope temps(this);
- Register scratch = r0;
+ Register scratch = temps.AcquireScratch();
AddS64(slot_reg, object,
Operand(OFFSET_OF_DATA_START(FixedArray) - kHeapObjectTag));
ShiftLeftU64(scratch, index, Operand(kTaggedSizeLog2));
@@ -1373,8 +1373,10 @@ inline void MaglevAssembler::CompareSmiAndAssert(Register src,
AbortReason reason) {
if (!v8_flags.debug_code) return;
AssertSmi(src);
- mov(r0, Operand(value.ptr()));
- CompareTagged(src, r0);
+ TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ mov(scratch, Operand(value.ptr()));
+ CompareTagged(src, scratch);
Assert(cond, reason);
}
diff --git a/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc b/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
index 95a3717a0f8..c8ae87e9323 100644
--- a/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
+++ b/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
@@ -440,6 +440,10 @@ void MaglevAssembler::StringCharCodeOrCodePointAt(
offsetof(SlicedString, offset_));
LoadTaggedField(string, string, offsetof(SlicedString, parent_));
Add32(index, index, Operand(offset));
+ // Add32 yields a sign-extended Word32. Normalize it to its unsigned form
+ // so that a (corrupted) negative offset cannot be interpreted as a
+ // negative index by the subsequent address computation.
+ ZeroExtendWord(index, index);
MacroAssembler::Branch(&loop, Label::kNear);
}
@@ -474,7 +478,12 @@ void MaglevAssembler::StringCharCodeOrCodePointAt(
// {instance_type} is unused from this point, so we can use as scratch.
Register scratch = instance_type;
- CalcScaledAddress(result, string, index, 1);
+ // On 64-bit, Maglev Word32 values are kept sign-extended, but the bounds
+ // check compares them as unsigned (zero-extended). Normalize the index to
+ // its unsigned form before using it in address arithmetic, so that a
+ // sign-extended (negative) index cannot reach below the string.
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(result, string, scratch, 1);
Lhu(result, MemOperand(result, OFFSET_OF_DATA_START(SeqTwoByteString) -
kHeapObjectTag));
@@ -491,7 +500,8 @@ void MaglevAssembler::StringCharCodeOrCodePointAt(
Label::kNear);
Register second_code_point = scratch;
- CalcScaledAddress(second_code_point, string, index, 1);
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(second_code_point, string, scratch, 1);
Lhu(second_code_point,
MemOperand(second_code_point,
OFFSET_OF_DATA_START(SeqTwoByteString) - kHeapObjectTag));
@@ -551,7 +561,12 @@ void MaglevAssembler::SeqOneByteStringCharCodeAt(Register result,
}
TemporaryRegisterScope scope(this);
Register scratch = scope.AcquireScratch();
- AddWord(scratch, index,
+ // On 64-bit, Maglev Word32 values are kept sign-extended, but the bounds
+ // check compares them as unsigned (zero-extended). Normalize the index to
+ // its unsigned form before using it in address arithmetic, so that a
+ // sign-extended (negative) index cannot reach below the string.
+ ZeroExtendWord(scratch, index);
+ AddWord(scratch, scratch,
Operand(OFFSET_OF_DATA_START(SeqOneByteString) - kHeapObjectTag));
AddWord(scratch, string, Operand(scratch));
Lbu(result, MemOperand(scratch, 0));
diff --git a/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc b/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
index 85498270ad8..beb9865edce 100644
--- a/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
+++ b/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
@@ -909,7 +909,7 @@ void Float64Min::GenerateCode(MaglevAssembler* masm,
DoubleRegister right = ToDoubleRegister(RightInput());
DoubleRegister out = ToDoubleRegister(result());
- __ FloatMinMaxHelper<double>(out, left, right, MaxMinKind::kMin);
+ __ Float64Min(out, left, right);
}
void Float64Max::SetValueLocationConstraints() {
@@ -932,7 +932,7 @@ void Float64Max::GenerateCode(MaglevAssembler* masm,
DoubleRegister right = ToDoubleRegister(RightInput());
DoubleRegister out = ToDoubleRegister(result());
- __ FloatMinMaxHelper<double>(out, left, right, MaxMinKind::kMax);
+ __ Float64Max(out, left, right);
}
int Float64Ieee754Unary::MaxCallStackArgs() const { return 0; }
diff --git a/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h b/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h
index 36c482fccd1..70f4aaa325a 100644
--- a/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h
+++ b/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h
@@ -495,6 +495,54 @@ inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(Register object,
MacroAssembler::StoreTaggedField(FieldOperand(object, offset), value);
}
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, ValueNode* constant) {
+ DCHECK(CanStoreTaggedConstant(constant));
+ switch (constant->opcode()) {
+ case Opcode::kSmiConstant:
+ MacroAssembler::StoreTaggedField(
+ FieldOperand(object, offset),
+ Immediate(constant->Cast<SmiConstant>()->value()));
+ break;
+ case Opcode::kRootConstant:
+ MacroAssembler::StoreTaggedField(
+ FieldOperand(object, offset),
+ Immediate(static_cast<int32_t>(
+ ReadOnlyRootPtr(constant->Cast<RootConstant>()->index()))));
+ break;
+ case Opcode::kHeapConstant:
+ StoreTaggedFieldNoWriteBarrier(
+ object, offset, constant->Cast<HeapConstant>()->object().object());
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(
+ Register object, int offset, Handle<HeapObject> constant) {
+ DCHECK(kSupportsStoreTaggedConstant);
+ RootIndex root_index;
+ if (isolate()->roots_table().IsRootHandle(constant, &root_index) &&
+ CanBeImmediate(root_index)) {
+ MacroAssembler::StoreTaggedField(
+ FieldOperand(object, offset),
+ Immediate(static_cast<int32_t>(ReadOnlyRootPtr(root_index))));
+ return;
+ }
+ // Embed the compressed object as a relocatable immediate, like
+ // {MacroAssembler::Move(Register, Handle<HeapObject>, RelocInfo::Mode)} does
+ // for the register form. Maglev code is never isolate-independent, so no
+ // root-relative load is needed.
+ DCHECK(!options().isolate_independent_code);
+ EmbeddedObjectIndex index = AddEmbeddedObject(constant);
+ DCHECK(is_uint32(index));
+ MacroAssembler::StoreTaggedField(
+ FieldOperand(object, offset),
+ Immediate(static_cast<int>(index),
+ RelocInfo::COMPRESSED_EMBEDDED_OBJECT));
+}
+
inline void MaglevAssembler::StoreFixedArrayElementNoWriteBarrier(
Register array, Register index, Register value) {
MacroAssembler::StoreTaggedField(
diff --git a/deps/v8/src/numbers/conversions.cc b/deps/v8/src/numbers/conversions.cc
index 3acdfa1a2ad..3bdae78df64 100644
--- a/deps/v8/src/numbers/conversions.cc
+++ b/deps/v8/src/numbers/conversions.cc
@@ -8,6 +8,7 @@
#include <stdarg.h>
#include <cmath>
+#include <limits>
#include <optional>
#include "include/v8config.h"
@@ -427,12 +428,14 @@ double InternalStringToIntDouble(const Char* start, const Char* end,
number >>= overflow_bits_count;
exponent = overflow_bits_count;
+ // Cap exponent to avoid int overflow on huge digit runs
+ constexpr int kMaxExponent = std::numeric_limits<double>::max_exponent;
bool zero_tail = true;
while (true) {
++current;
if (current == end || !isDigit(*current, radix)) break;
zero_tail = zero_tail && *current == '0';
- exponent += radix_log_2;
+ if (exponent <= kMaxExponent) exponent += radix_log_2;
}
if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) {
diff --git a/deps/v8/src/objects/all-objects.h b/deps/v8/src/objects/all-objects.h
index 76b8392e4d1..2f23535a30a 100644
--- a/deps/v8/src/objects/all-objects.h
+++ b/deps/v8/src/objects/all-objects.h
@@ -5,10 +5,15 @@
#ifndef V8_OBJECTS_ALL_OBJECTS_H_
#define V8_OBJECTS_ALL_OBJECTS_H_
-// This file reaches the declaration of every heap object. Keep this list to
+// This file includes every heap object header directly. Keep this list to
// plain headers: tools/metagen parses it before generated instance types and
// builtin definitions exist, and object layout generation only needs class
-// declarations. PRESUBMIT.py checks that the include closure stays complete.
+// declarations. PRESUBMIT.py checks that every V8_OBJECT header is listed.
+//
+// The includes must be direct because BUILD.gn declares only this file as an
+// input of the harvest. A header included through an intermediate header is
+// still harvested, but the intermediate is in neither the action's inputs nor
+// the depfile, so an incremental build keeps a stale instance-types.h.
#include "src/ic/handler-configuration.h"
#include "src/objects/abstract-code.h"
@@ -17,15 +22,19 @@
#include "src/objects/api-callbacks.h"
#include "src/objects/arguments.h"
#include "src/objects/bigint.h"
+#include "src/objects/bytecode-array.h"
#include "src/objects/call-site-info.h"
#include "src/objects/cell.h"
#include "src/objects/code.h"
#include "src/objects/compilation-cache-table.h"
#include "src/objects/compressed-slots.h"
#include "src/objects/contexts.h"
+#include "src/objects/cpp-heap-external-object.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/data-handler.h"
#include "src/objects/debug-objects.h"
+#include "src/objects/deoptimization-data.h"
+#include "src/objects/dependent-code.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/dictionary.h"
#include "src/objects/elements.h"
@@ -34,17 +43,22 @@
#include "src/objects/feedback-cell.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/field-index.h"
+#include "src/objects/fixed-array-base.h"
#include "src/objects/fixed-array.h"
+#include "src/objects/fixed-primitive-array.h"
#include "src/objects/foreign.h"
#include "src/objects/free-space.h"
#include "src/objects/hash-seed-wrapper.h"
#include "src/objects/hash-table.h"
#include "src/objects/heap-number.h"
#include "src/objects/heap-object.h"
+#include "src/objects/hole.h"
#include "src/objects/instance-type.h"
+#include "src/objects/instruction-stream.h"
#include "src/objects/js-array-buffer.h"
#include "src/objects/js-array.h"
#include "src/objects/js-atomics-synchronization.h"
+#include "src/objects/js-collection-iterator.h"
#include "src/objects/js-collection.h"
#include "src/objects/js-disposable-stack.h"
#include "src/objects/js-function.h"
@@ -59,6 +73,7 @@
#include "src/objects/js-regexp.h"
#include "src/objects/js-shadow-realm.h"
#include "src/objects/js-shared-array.h"
+#include "src/objects/js-struct.h"
#ifdef V8_TEMPORAL_SUPPORT
#include "src/objects/js-temporal-objects.h"
#endif // V8_TEMPORAL_SUPPORT
@@ -66,6 +81,7 @@
#include "src/objects/literal-objects.h"
#include "src/objects/lookup-cache.h"
#include "src/objects/lookup.h"
+#include "src/objects/managed.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object.h"
#include "src/objects/megadom-handler.h"
@@ -76,6 +92,8 @@
#include "src/objects/objects.h"
#include "src/objects/oddball.h"
#include "src/objects/ordered-hash-table.h"
+#include "src/objects/pod-array.h"
+#include "src/objects/primitive-heap-object.h"
#include "src/objects/promise.h"
#include "src/objects/property-array.h"
#include "src/objects/property-cell.h"
diff --git a/deps/v8/src/objects/backing-store.cc b/deps/v8/src/objects/backing-store.cc
index 74df6b3162c..feb9f85096b 100644
--- a/deps/v8/src/objects/backing-store.cc
+++ b/deps/v8/src/objects/backing-store.cc
@@ -323,7 +323,7 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
// For accounting purposes, whether a GC was necessary.
bool did_retry = false;
- auto gc_retry = [&](const auto& fn) {
+ auto gc_retry = [&](const std::function<bool()>& fn) {
if (fn()) return true;
// Collect garbage and retry.
did_retry = true;
diff --git a/deps/v8/src/objects/compilation-cache-table-inl.h b/deps/v8/src/objects/compilation-cache-table-inl.h
index 4e421b94ccf..bc628d13319 100644
--- a/deps/v8/src/objects/compilation-cache-table-inl.h
+++ b/deps/v8/src/objects/compilation-cache-table-inl.h
@@ -12,6 +12,7 @@
#include "src/objects/name-inl.h"
#include "src/objects/object-conversions-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/script-inl.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/smi.h"
diff --git a/deps/v8/src/objects/contexts-inl.h b/deps/v8/src/objects/contexts-inl.h
index 718f953280e..ee19a4f733a 100644
--- a/deps/v8/src/objects/contexts-inl.h
+++ b/deps/v8/src/objects/contexts-inl.h
@@ -10,7 +10,6 @@
#include "src/common/globals.h"
#include "src/heap/heap-write-barrier-inl.h"
-#include "src/heap/heap-write-barrier.h"
#include "src/objects/casting.h"
#include "src/objects/fixed-array-inl.h"
#include "src/objects/heap-object-field-inl.h"
@@ -68,14 +67,21 @@ void Context::set_length(int value, RelaxedStoreTag) {
length_.Relaxed_Store_no_write_barrier(Smi::FromInt(value));
}
-bool Context::IsElementTheHole(int index) {
- return IsTheHole(get(index, kRelaxedLoad));
+bool Context::IsElementTdzHole(int index) {
+ Tagged<Object> value = get(index, kRelaxedLoad);
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(value));
+#endif
+ return IsTdzHole(value);
}
template <typename MemoryTag>
Tagged<Object> Context::GetNoCell(int index, MemoryTag tag) {
Tagged<Object> value = get(index, tag);
DCHECK(!Is<ContextCell>(value));
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(value));
+#endif
return value;
}
@@ -87,6 +93,9 @@ template <typename MemoryTag>
void Context::SetNoCell(int index, Tagged<Object> value, MemoryTag tag,
WriteBarrierMode mode) {
DCHECK(!Is<ContextCell>(get(index, kRelaxedLoad)));
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(value));
+#endif
set(index, value, mode, tag);
}
@@ -239,61 +248,6 @@ inline bool Context::HasContextCells() const {
NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSORS)
#undef NATIVE_CONTEXT_FIELD_ACCESSORS
-#define CHECK_FOLLOWS2(v1, v2) static_assert((v1 + 1) == (v2))
-#define CHECK_FOLLOWS4(v1, v2, v3, v4) \
- CHECK_FOLLOWS2(v1, v2); \
- CHECK_FOLLOWS2(v2, v3); \
- CHECK_FOLLOWS2(v3, v4)
-
-int Context::FunctionMapIndex(LanguageMode language_mode, FunctionKind kind,
- bool has_shared_name) {
- if (IsClassConstructor(kind)) {
- // Like the strict function map, but with no 'name' accessor. 'name'
- // needs to be the last property and it is added during instantiation,
- // in case a static property with the same name exists"
- return CLASS_FUNCTION_MAP_INDEX;
- }
-
- int base = 0;
- if (IsGeneratorFunction(kind)) {
- CHECK_FOLLOWS2(GENERATOR_FUNCTION_MAP_INDEX,
- GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX);
- CHECK_FOLLOWS2(ASYNC_GENERATOR_FUNCTION_MAP_INDEX,
- ASYNC_GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX);
-
- base = IsAsyncFunction(kind) ? ASYNC_GENERATOR_FUNCTION_MAP_INDEX
- : GENERATOR_FUNCTION_MAP_INDEX;
-
- } else if (IsAsyncFunction(kind) || IsModuleWithTopLevelAwait(kind)) {
- CHECK_FOLLOWS2(ASYNC_FUNCTION_MAP_INDEX,
- ASYNC_FUNCTION_WITH_NAME_MAP_INDEX);
-
- base = ASYNC_FUNCTION_MAP_INDEX;
-
- } else if (IsStrictFunctionWithoutPrototype(kind)) {
- CHECK_FOLLOWS2(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
- METHOD_WITH_NAME_MAP_INDEX);
-
- base = STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
-
- } else {
- CHECK_FOLLOWS2(SLOPPY_FUNCTION_MAP_INDEX,
- SLOPPY_FUNCTION_WITH_NAME_MAP_INDEX);
- CHECK_FOLLOWS2(STRICT_FUNCTION_MAP_INDEX,
- STRICT_FUNCTION_WITH_NAME_MAP_INDEX);
-
- base = is_strict(language_mode) ? STRICT_FUNCTION_MAP_INDEX
- : SLOPPY_FUNCTION_MAP_INDEX;
- }
- int offset = static_cast<int>(!has_shared_name);
- DCHECK_EQ(0, offset & ~1);
-
- return base + offset;
-}
-
-#undef CHECK_FOLLOWS2
-#undef CHECK_FOLLOWS4
-
Tagged<Map> Context::GetInitialJSArrayMap(ElementsKind kind) const {
DCHECK(Is<NativeContext>(this));
if (!IsFastElementsKind(kind)) return {};
@@ -312,16 +266,15 @@ MicrotaskQueue* NativeContext::microtask_queue() const {
MicrotaskQueue* NativeContext::microtask_queue(
IsolateForPointerCompression isolate) const {
return reinterpret_cast<MicrotaskQueue*>(
- ReadCppHeapPointerField<CppHeapPointerTag::kMicrotaskQueueTag,
- CppHeapPointerTag::kMicrotaskQueueTag>(
+ ReadCppHeapPointerField<kMicrotaskQueueTag, kMicrotaskQueueTag>(
kMicrotaskQueueOffset, isolate));
}
void NativeContext::set_microtask_queue(IsolateForPointerCompression isolate,
MicrotaskQueue* queue) {
- WriteLazilyInitializedCppHeapPointerField(
- kMicrotaskQueueOffset, isolate, reinterpret_cast<Address>(queue),
- CppHeapPointerTag::kMicrotaskQueueTag);
+ WriteLazilyInitializedCppHeapPointerField(kMicrotaskQueueOffset, isolate,
+ reinterpret_cast<Address>(queue),
+ kMicrotaskQueueTag);
WriteBarrier::ForCppHeapPointer(Tagged<NativeContext>(this),
RawCppHeapPointerField(kMicrotaskQueueOffset),
queue);
diff --git a/deps/v8/src/objects/contexts.cc b/deps/v8/src/objects/contexts.cc
index dbbce4899f0..69e0506382f 100644
--- a/deps/v8/src/objects/contexts.cc
+++ b/deps/v8/src/objects/contexts.cc
@@ -105,12 +105,62 @@ Handle<ScriptContextTable> ScriptContextTable::Add(
return result;
}
+#define CHECK_FOLLOWS2(v1, v2) static_assert((v1 + 1) == (v2))
+
+int Context::FunctionMapIndex(LanguageMode language_mode, FunctionKind kind,
+ bool has_shared_name) {
+ if (IsClassConstructor(kind)) {
+ // Like the strict function map, but with no 'name' accessor. 'name'
+ // needs to be the last property and it is added during instantiation,
+ // in case a static property with the same name exists"
+ return CLASS_FUNCTION_MAP_INDEX;
+ }
+
+ int base = 0;
+ if (IsGeneratorFunction(kind)) {
+ CHECK_FOLLOWS2(GENERATOR_FUNCTION_MAP_INDEX,
+ GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX);
+ CHECK_FOLLOWS2(ASYNC_GENERATOR_FUNCTION_MAP_INDEX,
+ ASYNC_GENERATOR_FUNCTION_WITH_NAME_MAP_INDEX);
+
+ base = IsAsyncFunction(kind) ? ASYNC_GENERATOR_FUNCTION_MAP_INDEX
+ : GENERATOR_FUNCTION_MAP_INDEX;
+
+ } else if (IsAsyncFunction(kind) || IsModuleWithTopLevelAwait(kind)) {
+ CHECK_FOLLOWS2(ASYNC_FUNCTION_MAP_INDEX,
+ ASYNC_FUNCTION_WITH_NAME_MAP_INDEX);
+
+ base = ASYNC_FUNCTION_MAP_INDEX;
+
+ } else if (IsStrictFunctionWithoutPrototype(kind)) {
+ CHECK_FOLLOWS2(STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
+ METHOD_WITH_NAME_MAP_INDEX);
+
+ base = STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX;
+
+ } else {
+ CHECK_FOLLOWS2(SLOPPY_FUNCTION_MAP_INDEX,
+ SLOPPY_FUNCTION_WITH_NAME_MAP_INDEX);
+ CHECK_FOLLOWS2(STRICT_FUNCTION_MAP_INDEX,
+ STRICT_FUNCTION_WITH_NAME_MAP_INDEX);
+
+ base = is_strict(language_mode) ? STRICT_FUNCTION_MAP_INDEX
+ : SLOPPY_FUNCTION_MAP_INDEX;
+ }
+ int offset = static_cast<int>(!has_shared_name);
+ DCHECK_EQ(0, offset & ~1);
+
+ return base + offset;
+}
+
+#undef CHECK_FOLLOWS2
+
void Context::Initialize(Isolate* isolate) {
Tagged<ScopeInfo> scope_info = this->scope_info();
int header = scope_info->ContextHeaderLength();
for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
if (scope_info->ContextLocalInitFlag(var) == kNeedsInitialization) {
- set(header + var, ReadOnlyRoots(isolate).the_hole_value());
+ set(header + var, ReadOnlyRoots(isolate).tdz_hole_value());
}
}
}
@@ -353,7 +403,7 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name,
// context of the first script that declared a variable, all other
// script contexts will contain 'the hole' for that particular name.
if (scope_info->IsReplModeScope() &&
- context->IsElementTheHole(slot_index)) {
+ context->IsElementTdzHole(slot_index)) {
context = Handle<Context>(context->previous(), isolate);
continue;
}
@@ -516,7 +566,10 @@ DirectHandle<Object> Context::Get(DirectHandle<Context> context, int index,
Isolate* isolate) {
DirectHandle<Object> value =
handle(context->get(index, kRelaxedLoad), isolate);
- if (IsTheHole(*value) || !Is<ContextCell>(value)) {
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*value));
+#endif
+ if (IsTdzHole(*value) || !Is<ContextCell>(value)) {
return value;
}
DCHECK(context->HasContextCells());
@@ -543,12 +596,16 @@ DirectHandle<Object> Context::Get(DirectHandle<Context> context, int index,
void Context::Set(DirectHandle<Context> context, int index,
DirectHandle<Object> new_value, Isolate* isolate) {
DirectHandle<Object> old_value(context->get(index, kRelaxedLoad), isolate);
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*old_value));
+ DCHECK(!IsTheHole(*new_value));
+#endif
if (!context->HasContextCells()) {
context->set(index, *new_value);
return;
}
- if (IsTheHole(*old_value)) {
+ if (IsTdzHole(*old_value)) {
// Setting the initial value.
DirectHandle<ContextCell> cell =
isolate->factory()->NewContextCell(Cast<JSAny>(new_value));
@@ -563,7 +620,7 @@ void Context::Set(DirectHandle<Context> context, int index,
if (IsUndefinedContextCell(*old_value)) {
if (IsUndefined(*new_value)) return;
- if (IsTheHole(*new_value)) {
+ if (IsTdzHole(*new_value)) {
// This can happened in let-variable in function contexts.
context->set(index, *new_value);
return;
diff --git a/deps/v8/src/objects/contexts.h b/deps/v8/src/objects/contexts.h
index e22720c8efd..90a1efd85bd 100644
--- a/deps/v8/src/objects/contexts.h
+++ b/deps/v8/src/objects/contexts.h
@@ -502,7 +502,7 @@ V8_OBJECT class Context : public HeapObject {
inline int length(RelaxedLoadTag) const;
inline void set_length(int value, RelaxedStoreTag);
- V8_INLINE bool IsElementTheHole(int index);
+ V8_INLINE bool IsElementTdzHole(int index);
template <typename MemoryTag>
V8_INLINE Tagged<Object> GetNoCell(int index, MemoryTag tag);
@@ -687,8 +687,9 @@ V8_OBJECT class Context : public HeapObject {
VariableMode* variable_mode,
bool* is_sloppy_function_name = nullptr);
- static inline int FunctionMapIndex(LanguageMode language_mode,
- FunctionKind kind, bool has_shared_name);
+ V8_EXPORT_PRIVATE static int FunctionMapIndex(LanguageMode language_mode,
+ FunctionKind kind,
+ bool has_shared_name);
static int ArrayMapIndex(ElementsKind elements_kind) {
DCHECK(IsFastElementsKind(elements_kind));
@@ -732,8 +733,8 @@ V8_OBJECT class Context : public HeapObject {
private:
#ifdef DEBUG
// Bootstrapping-aware type checks.
- static bool IsBootstrappingOrValidParentContext(Tagged<Object> object,
- Tagged<Context> kid);
+ V8_EXPORT_PRIVATE static bool IsBootstrappingOrValidParentContext(
+ Tagged<Object> object, Tagged<Context> kid);
#endif
friend class Factory;
diff --git a/deps/v8/src/objects/contexts.tq b/deps/v8/src/objects/contexts.tq
index 7d74f08a311..2fec4305baf 100644
--- a/deps/v8/src/objects/contexts.tq
+++ b/deps/v8/src/objects/contexts.tq
@@ -282,12 +282,12 @@ macro StoreContextElement(c: Context, i: constexpr int32, o: Object): void {
macro LoadContextElementNoCellImpl(c: Context, i: intptr): Object {
const val = c.elements[i];
- dcheck(Is<TheHole>(val) || !Is<ContextCell>(val));
+ dcheck(Is<TdzHole>(val) || !Is<ContextCell>(val));
return val;
}
macro StoreContextElementNoCellImpl(c: Context, i: intptr, o: Object): void {
- dcheck(Is<TheHole>(c.elements[i]) || !Is<ContextCell>(c.elements[i]));
+ dcheck(Is<TdzHole>(c.elements[i]) || !Is<ContextCell>(c.elements[i]));
c.elements[i] = o;
}
@@ -367,7 +367,7 @@ macro StoreScriptContextElementImpl(
c: Context, index: intptr, newValue: Object): void {
const oldValue = c.elements[index];
- if (oldValue == TheHole && HasContextCells(c)) {
+ if (oldValue == TdzHole && HasContextCells(c)) {
// Setting the initial value.
c.elements[index] = AllocateContextCell(newValue);
return;
@@ -380,7 +380,7 @@ macro StoreScriptContextElementImpl(
if (IsUndefinedContextCell(oldValue)) {
if (newValue == Undefined) return;
- if (newValue == TheHole) {
+ if (newValue == TdzHole) {
c.elements[index] = newValue;
return;
}
diff --git a/deps/v8/src/objects/embedder-data-slot-inl.h b/deps/v8/src/objects/embedder-data-slot-inl.h
index 34c8b8fa955..aaefba795c3 100644
--- a/deps/v8/src/objects/embedder-data-slot-inl.h
+++ b/deps/v8/src/objects/embedder-data-slot-inl.h
@@ -136,8 +136,7 @@ bool EmbedderDataSlot::ToAlignedPointer(
IsolateForPointerCompression isolate, void** out_pointer,
ExternalPointerTagRange tag_range) const {
void* raw_ptr = nullptr;
- if (!ToAlignedPointer(isolate, &raw_ptr,
- {CppHeapPointerTag::kEmbedderDataSlotTag})) {
+ if (!ToAlignedPointer(isolate, &raw_ptr, {kEmbedderDataSlotTag})) {
*out_pointer = nullptr;
return false;
}
@@ -185,7 +184,7 @@ bool EmbedderDataSlot::store_aligned_pointer(Isolate* isolate,
CppHeapPointerTable::Space* space =
IsolateForPointerCompression(isolate).GetCppHeapPointerTableSpace();
handle = table.AllocateAndInitializeEntry(space, value, tag);
- slot.Relaxed_StoreHandle(handle);
+ slot.Release_StoreHandle(handle);
} else {
table.Set(handle, value, tag);
}
@@ -224,7 +223,7 @@ bool EmbedderDataSlot::store_aligned_pointer(
DisallowGarbageCollection no_gc;
EmbedderDataSlot slot(*host, entry_or_embedder_field_index);
return slot.store_aligned_pointer(isolate, *host, wrapper,
- CppHeapPointerTag::kEmbedderDataSlotTag);
+ kEmbedderDataSlotTag);
}
#ifdef V8_COMPRESS_POINTERS
@@ -244,7 +243,7 @@ bool EmbedderDataSlot::store_handle_without_barrier(
CppHeapPointerSlot slot(address() + kCppHeapPointerOffset);
DCHECK_EQ(slot.Relaxed_LoadHandle(), kNullCppHeapPointerHandle);
- slot.Relaxed_StoreHandle(new_handle);
+ slot.Release_StoreHandle(new_handle);
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(Smi::zero());
return true;
diff --git a/deps/v8/src/objects/feedback-vector-inl.h b/deps/v8/src/objects/feedback-vector-inl.h
index b0179811c49..039d919757d 100644
--- a/deps/v8/src/objects/feedback-vector-inl.h
+++ b/deps/v8/src/objects/feedback-vector-inl.h
@@ -357,6 +357,11 @@ Tagged<FeedbackCell> FeedbackVector::closure_feedback_cell(int index) const {
Tagged<MaybeObject> FeedbackVector::SynchronizedGet(FeedbackSlot slot) const {
const int i = slot.ToInt();
DCHECK_LT(static_cast<unsigned>(i), static_cast<unsigned>(this->length()));
+
+ // See comment in SynchronizedSet.
+ DCHECK_NE(FeedbackSlotKind::kInvalid, GetKind(slot, kAcquireLoad));
+ DCHECK_EQ(1, FeedbackMetadata::GetSlotSize(GetKind(slot, kAcquireLoad)));
+
Tagged<MaybeObject> value = raw_feedback_slots()[i].Acquire_Load();
DCHECK(!IsOfLegacyType(value));
return value;
@@ -368,6 +373,20 @@ void FeedbackVector::SynchronizedSet(FeedbackSlot slot,
DCHECK(!IsOfLegacyType(value));
const int i = slot.ToInt();
DCHECK_LT(static_cast<unsigned>(i), static_cast<unsigned>(this->length()));
+
+ // Release-acquire semantics are only used for C++ accesses to slots of size
+ // 1. Longer slots are read as a group under the feedback_vector_access mutex
+ // (NexusConfig::GetFeedbackPair), so C++ writes must hold that mutex.
+ //
+ // Generated code is an exception and accesses slots without the mutex or
+ // release-acquire; its safety has to be checked case-by-case.
+ //
+ // Note that only the first slot of a group has a kind; accessing any of the
+ // following ones returns FeedbackSlotKind::kInvalid and fails the DCHECK_NE
+ // below.
+ DCHECK_NE(FeedbackSlotKind::kInvalid, GetKind(slot));
+ DCHECK_EQ(1, FeedbackMetadata::GetSlotSize(GetKind(slot)));
+
raw_feedback_slots()[i].Release_Store(this, value, mode);
}
@@ -597,6 +616,12 @@ void FeedbackNexus::SetFeedback(Tagged<FeedbackType> feedback,
mode_extra);
}
+template <typename FeedbackExtraType>
+void FeedbackNexus::SetFeedbackExtra(Tagged<FeedbackExtraType> feedback_extra,
+ WriteBarrierMode mode_extra) {
+ config()->SetFeedbackExtra(vector(), slot(), feedback_extra, mode_extra);
+}
+
template <typename F>
void FeedbackNexus::IterateMapsWithUnclearedHandler(F function) const {
// We don't need DisallowGarbageCollection here: accessing it.map() and
diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc
index 7b3a481bd77..a90afb2f29d 100644
--- a/deps/v8/src/objects/feedback-vector.cc
+++ b/deps/v8/src/objects/feedback-vector.cc
@@ -17,6 +17,7 @@
#include "src/ic/ic-inl.h"
#include "src/objects/code-inl.h"
#include "src/objects/data-handler-inl.h"
+#include "src/objects/dictionary.h"
#include "src/objects/feedback-cell.h"
#include "src/objects/feedback-vector-inl.h"
#include "src/objects/hash-table-inl.h"
@@ -495,14 +496,42 @@ void NexusConfig::SetFeedbackPair(Tagged<FeedbackVector> vector,
WriteBarrierMode mode_extra) const {
CHECK(can_write());
CHECK_GT(vector->length().value(), start_slot.WithOffset(1).ToInt());
+
+ // This function (and locking the feedback_vector_access mutex) only makes
+ // sense for slots longer than 1.
+ DCHECK_NE(FeedbackSlotKind::kInvalid, vector->GetKind(start_slot));
+ DCHECK_GE(FeedbackMetadata::GetSlotSize(vector->GetKind(start_slot)), 2);
+
base::MutexGuard mutex_guard(isolate()->feedback_vector_access());
vector->Set(start_slot, feedback, mode);
vector->Set(start_slot.WithOffset(1), feedback_extra, mode_extra);
}
+void NexusConfig::SetFeedbackExtra(Tagged<FeedbackVector> vector,
+ FeedbackSlot start_slot,
+ Tagged<MaybeObject> feedback_extra,
+ WriteBarrierMode mode_extra) const {
+ CHECK(can_write());
+ CHECK_GT(vector->length().value(), start_slot.WithOffset(1).ToInt());
+
+ // This function (and locking the feedback_vector_access mutex) only makes
+ // sense for slots longer than 1.
+ DCHECK_NE(FeedbackSlotKind::kInvalid, vector->GetKind(start_slot));
+ DCHECK_GE(FeedbackMetadata::GetSlotSize(vector->GetKind(start_slot)), 2);
+
+ base::MutexGuard mutex_guard(isolate()->feedback_vector_access());
+ vector->Set(start_slot.WithOffset(1), feedback_extra, mode_extra);
+}
+
std::pair<Tagged<MaybeObject>, Tagged<MaybeObject>>
NexusConfig::GetFeedbackPair(Tagged<FeedbackVector> vector,
FeedbackSlot slot) const {
+ // This function (and locking the feedback_vector_access mutex) only makes
+ // sense for slots longer than 1.
+ DCHECK_NE(FeedbackSlotKind::kInvalid, vector->GetKind(slot, kAcquireLoad));
+ DCHECK_GE(FeedbackMetadata::GetSlotSize(vector->GetKind(slot, kAcquireLoad)),
+ 2);
+
base::MutexGuardIf guard(isolate()->feedback_vector_access(),
mode() == BackgroundThread);
Tagged<MaybeObject> feedback = vector->Get(slot);
@@ -1050,7 +1079,7 @@ void FeedbackNexus::ConfigureCloneObject(
for (uint32_t j = 0; j < array_len; ++j) {
new_array->set(j, array->get(j));
}
- SetFeedback(*new_array);
+ SetFeedback(*new_array, UPDATE_WRITE_BARRIER, kClearedWeakValue);
array = new_array;
}
@@ -1064,6 +1093,15 @@ void FeedbackNexus::ConfigureCloneObject(
}
}
+void FeedbackNexus::ConfigureStringAddInternalizeCache(
+ Tagged<SimpleNameDictionary> cache) {
+ DisallowGarbageCollection no_gc;
+ DCHECK_EQ(kind(), FeedbackSlotKind::kStringAddAndInternalize);
+ // The cache is stored in the extra slot; the binary operation hint in the
+ // main slot is left as it is.
+ SetFeedbackExtra(cache);
+}
+
int FeedbackNexus::GetCallCount() {
DCHECK(IsCallICKind(kind()));
@@ -1080,11 +1118,7 @@ void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) {
CHECK(IsSmi(call_count));
uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count));
count = SpeculationModeField::update(count, mode);
- Tagged<MaybeObject> feedback = GetFeedback();
- // We could've skipped WB here (since we set the slot to the same value again)
- // but we don't to make WB verification happy.
- SetFeedback(feedback, UPDATE_WRITE_BARRIER, Smi::FromInt(count),
- SKIP_WRITE_BARRIER);
+ SetFeedbackExtra(Smi::FromInt(count), SKIP_WRITE_BARRIER);
}
void FeedbackNexus::NextSpeculationMode(SpeculationMode mode) {
diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h
index 079645e33e8..680605538cf 100644
--- a/deps/v8/src/objects/feedback-vector.h
+++ b/deps/v8/src/objects/feedback-vector.h
@@ -30,6 +30,7 @@ namespace v8::internal {
class IsCompiledScope;
class FeedbackVectorSpec;
+class SimpleNameDictionary;
enum class UpdateFeedbackMode {
kOptionalFeedback,
@@ -427,6 +428,7 @@ V8_OBJECT class FeedbackVector : public HeapObject {
// Conversion from an integer index to the underlying array to a slot.
static inline FeedbackSlot ToSlot(intptr_t index);
+ // Use only for 1-sized slots. For longer slots, use FeedbackNexus helpers.
inline Tagged<MaybeObject> SynchronizedGet(FeedbackSlot slot) const;
inline void SynchronizedSet(FeedbackSlot slot, Tagged<MaybeObject> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -954,6 +956,12 @@ class V8_EXPORT_PRIVATE NexusConfig {
Tagged<MaybeObject> feedback, WriteBarrierMode mode,
Tagged<MaybeObject> feedback_extra,
WriteBarrierMode mode_extra) const;
+ // Writes only the extra slot, leaving the main slot as it is. Like
+ // SetFeedbackPair, this takes the feedback_vector_access mutex, which is what
+ // readers of the slot group rely on.
+ void SetFeedbackExtra(Tagged<FeedbackVector> vector, FeedbackSlot start_slot,
+ Tagged<MaybeObject> feedback_extra,
+ WriteBarrierMode mode_extra) const;
private:
explicit NexusConfig(Isolate* isolate)
@@ -1115,6 +1123,9 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
void ConfigureCloneObject(DirectHandle<Map> source_map,
const MaybeObjectHandle& handler);
+ // For StringAddAndInternalize ICs.
+ void ConfigureStringAddInternalizeCache(Tagged<SimpleNameDictionary> cache);
+
// Bit positions in a smi that encodes lexical environment variable access.
#define LEXICAL_MODE_BIT_FIELDS(V, _) \
V(ContextIndexBits, unsigned, 12, _) \
@@ -1135,6 +1146,10 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
inline void SetFeedback(Tagged<FeedbackType> feedback, WriteBarrierMode mode,
Tagged<FeedbackExtraType> feedback_extra,
WriteBarrierMode mode_extra = UPDATE_WRITE_BARRIER);
+ template <typename FeedbackExtraType>
+ inline void SetFeedbackExtra(
+ Tagged<FeedbackExtraType> feedback_extra,
+ WriteBarrierMode mode_extra = UPDATE_WRITE_BARRIER);
inline Tagged<MaybeObject> UninitializedSentinel() const;
inline Tagged<MaybeObject> MegamorphicSentinel() const;
diff --git a/deps/v8/src/objects/heap-object-field-inl.h b/deps/v8/src/objects/heap-object-field-inl.h
index 92085c27b4b..591dfc7f395 100644
--- a/deps/v8/src/objects/heap-object-field-inl.h
+++ b/deps/v8/src/objects/heap-object-field-inl.h
@@ -53,20 +53,22 @@ void HeapObject::InitExternalPointerField(size_t offset,
IsolateForSandbox isolate,
Address value,
WriteBarrierMode mode) {
- i::InitExternalPointerField<tag>(address(), field_address(offset), isolate,
- value);
+ ExternalPointerHandle handle = i::InitExternalPointerField<tag>(
+ address(), field_address(offset), isolate, value);
CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(this, static_cast<int>(offset),
- tag, mode);
+ tag, handle, mode);
+ USE(handle);
}
void HeapObject::InitExternalPointerField(size_t offset,
IsolateForSandbox isolate,
ExternalPointerTag tag, Address value,
WriteBarrierMode mode) {
- i::InitExternalPointerField(address(), field_address(offset), isolate, tag,
- value);
+ ExternalPointerHandle handle = i::InitExternalPointerField(
+ address(), field_address(offset), isolate, tag, value);
CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(this, static_cast<int>(offset),
- tag, mode);
+ tag, handle, mode);
+ USE(handle);
}
template <ExternalPointerTagRange tag_range>
@@ -153,7 +155,7 @@ void HeapObject::WriteLazilyInitializedExternalPointerField(
base::AsAtomic32::Release_Store(location, handle);
// In this case, we're adding a reference from an existing object to a new
// table entry, so we always require a write barrier.
- EXTERNAL_POINTER_WRITE_BARRIER(this, static_cast<int>(offset), tag);
+ EXTERNAL_POINTER_WRITE_BARRIER(this, static_cast<int>(offset), tag, handle);
} else {
table.Set(handle, value, tag);
}
diff --git a/deps/v8/src/objects/heap-object.h b/deps/v8/src/objects/heap-object.h
index 0983cce69f6..60f64116d4e 100644
--- a/deps/v8/src/objects/heap-object.h
+++ b/deps/v8/src/objects/heap-object.h
@@ -432,6 +432,9 @@ IS_TYPE_FUNCTION_DECL(AnyHole)
V8_INLINE bool Is##Type(Tagged<HeapObject> obj);
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
HOLE_LIST(IS_TYPE_FUNCTION_DECL)
+#ifndef V8_ENABLE_TDZ_HOLE
+IS_TYPE_FUNCTION_DECL(TdzHole)
+#endif
IS_TYPE_FUNCTION_DECL(UndefinedContextCell)
IS_TYPE_FUNCTION_DECL(NullOrUndefined)
#undef IS_TYPE_FUNCTION_DECL
diff --git a/deps/v8/src/objects/hole.h b/deps/v8/src/objects/hole.h
index ab21eea43f4..71c463931c7 100644
--- a/deps/v8/src/objects/hole.h
+++ b/deps/v8/src/objects/hole.h
@@ -42,6 +42,9 @@ V8_OBJECT class Hole : public HeapObject {
HOLE_LIST(DEFINE_HOLE_TYPE)
#undef DEFINE_HOLE_TYPE
+#ifndef V8_ENABLE_TDZ_HOLE
+using TdzHole = TheHole;
+#endif
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/hole.tq b/deps/v8/src/objects/hole.tq
index 5cda0215799..421c6952606 100644
--- a/deps/v8/src/objects/hole.tq
+++ b/deps/v8/src/objects/hole.tq
@@ -11,3 +11,5 @@ extern class TheHole extends Hole;
@hasSameInstanceTypeAsParent
@doNotGenerateCast
extern class PromiseHole extends Hole;
+
+type TdzHole extends Hole generates 'TdzHole';
diff --git a/deps/v8/src/objects/intl-objects.cc b/deps/v8/src/objects/intl-objects.cc
index 7a36b11b33d..705ce2d6f62 100644
--- a/deps/v8/src/objects/intl-objects.cc
+++ b/deps/v8/src/objects/intl-objects.cc
@@ -1087,8 +1087,7 @@ std::optional<int> Intl::StringLocaleCompare(Isolate* isolate,
MaybeDirectHandle<JSCollator> maybe_collator =
New<JSCollator>(isolate, constructor, locales, options, method_name);
if (!maybe_collator.ToHandle(&collator)) return {};
- CppGCManaged<icu::Collator>::Ptr icu_collator =
- collator->icu_collator()->ptr();
+ Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
if (can_cache) {
isolate->set_icu_object_in_cache(
Isolate::ICUObjectCacheType::kDefaultCollator, locales,
@@ -1607,7 +1606,7 @@ MaybeDirectHandle<String> Intl::NumberToLocaleString(
isolate, number_format,
New<JSNumberFormat>(isolate, constructor, locales, options, method_name));
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
number_format->icu_number_formatter()->ptr();
if (can_cache) {
diff --git a/deps/v8/src/objects/intl-objects.h b/deps/v8/src/objects/intl-objects.h
index 9487fa94646..6ea9427d1f4 100644
--- a/deps/v8/src/objects/intl-objects.h
+++ b/deps/v8/src/objects/intl-objects.h
@@ -47,20 +47,18 @@ class Notation;
namespace v8::internal {
-#define ICU_MANAGED_TYPE_ID_LIST(V) \
- V(icu::BreakIterator, ManagedTypeId::kIcuBreakIterator) \
- V(icu::Locale, ManagedTypeId::kIcuLocale) \
- V(icu::SimpleDateFormat, ManagedTypeId::kIcuSimpleDateFormat) \
- V(icu::DateIntervalFormat, ManagedTypeId::kIcuDateIntervalFormat) \
- V(icu::RelativeDateTimeFormatter, \
- ManagedTypeId::kIcuRelativeDateTimeFormatter) \
- V(icu::ListFormatter, ManagedTypeId::kIcuListFormatter) \
- V(icu::Collator, ManagedTypeId::kIcuCollator) \
- V(icu::PluralRules, ManagedTypeId::kIcuPluralRules) \
- V(icu::number::LocalizedNumberFormatter, \
- ManagedTypeId::kIcuLocalizedNumberFormatter)
-ICU_MANAGED_TYPE_ID_LIST(ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED)
-#undef ICU_MANAGED_TYPE_ID_LIST
+#define ICU_EXTERNAL_POINTER_TAG_LIST(V) \
+ V(icu::BreakIterator, kIcuBreakIteratorTag) \
+ V(icu::Locale, kIcuLocaleTag) \
+ V(icu::SimpleDateFormat, kIcuSimpleDateFormatTag) \
+ V(icu::DateIntervalFormat, kIcuDateIntervalFormatTag) \
+ V(icu::RelativeDateTimeFormatter, kIcuRelativeDateTimeFormatterTag) \
+ V(icu::ListFormatter, kIcuListFormatterTag) \
+ V(icu::Collator, kIcuCollatorTag) \
+ V(icu::PluralRules, kIcuPluralRulesTag) \
+ V(icu::number::LocalizedNumberFormatter, kIcuLocalizedNumberFormatterTag)
+ICU_EXTERNAL_POINTER_TAG_LIST(ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED)
+#undef ICU_EXTERNAL_POINTER_TAG_LIST
struct NumberFormatSpan {
int32_t field_id;
diff --git a/deps/v8/src/objects/js-array-buffer-inl.h b/deps/v8/src/objects/js-array-buffer-inl.h
index 79c39f07268..ca6ca483ba9 100644
--- a/deps/v8/src/objects/js-array-buffer-inl.h
+++ b/deps/v8/src/objects/js-array-buffer-inl.h
@@ -94,41 +94,30 @@ size_t JSArrayBuffer::GetByteLength() const {
if (ext == nullptr) {
return 0;
}
+ ext->InitializationBarrier();
SBXCHECK(ext->is_shared() && ext->is_resizable_by_js());
return ext->backing_store()->byte_length(std::memory_order_seq_cst);
}
- // We should not be reading the JS-visible byte length of a RAB from a
- // background thread, unless the mutator is guaranteed to be paused. This
- // happens during a GC pause, during teardown, or when the main thread is
- // parked.
- DCHECK_IMPLIES(
- is_resizable && !is_shared_ && LocalHeap::Current() != nullptr &&
- !LocalHeap::Current()->is_main_thread(),
- LocalHeap::Current()->heap()->IsInGC() ||
- LocalHeap::Current()->heap()->IsTearingDown() ||
- LocalHeap::Current()->heap()->main_thread_local_heap()->IsParked());
+ // Non-shared ArrayBuffers must only have their byte length read from the main
+ // thread to avoid data races (as the main thread may update it when
+ // materializing an on-heap TypedArray's buffer, detaching, or resizing).
+ //
+ // For non-resizable SharedArrayBuffers, byte_length is immutable after
+ // construction, so it can safely be read from a background thread (e.g.
+ // during concurrent memory measurement).
+ DCHECK(is_shared_ || LocalHeap::Current()->is_main_thread());
return byte_length();
}
-uint32_t JSArrayBuffer::GetBackingStoreRefForDeserialization() const {
- return static_cast<uint32_t>(
- ReadField<Address>(offsetof(JSArrayBuffer, backing_store_)));
-}
-
-void JSArrayBuffer::SetBackingStoreRefForSerialization(uint32_t ref) {
- WriteField<Address>(offsetof(JSArrayBuffer, backing_store_),
- static_cast<Address>(ref));
-}
-
void JSArrayBuffer::init_extension() {
#if V8_COMPRESS_POINTERS
// The extension field is lazily-initialized, so set it to null initially.
- base::AsAtomic32::Release_Store(extension_handle_location(),
+ base::AsAtomic32::Relaxed_Store(extension_handle_location(),
kNullExternalPointerHandle);
#else
- base::AsAtomicPointer::Release_Store(extension_location(), nullptr);
+ base::AsAtomicPointer::Relaxed_Store(extension_location(), nullptr);
#endif // V8_COMPRESS_POINTERS
}
@@ -158,8 +147,9 @@ void JSArrayBuffer::set_extension(ArrayBufferExtension* extension) {
if (current_handle == kNullExternalPointerHandle) {
ExternalPointerHandle handle = table.AllocateAndInitializeEntry(
isolate.GetExternalPointerTableSpaceFor(tag, address()), value, tag);
- base::AsAtomic32::Relaxed_Store(extension_handle_location(), handle);
- WriteBarrier::ForExternalPointer(this, ExternalPointerSlot(&extension_));
+ base::AsAtomic32::Release_Store(extension_handle_location(), handle);
+ WriteBarrier::ForExternalPointer(this, ExternalPointerSlot(&extension_),
+ handle);
} else {
table.Set(current_handle, value, tag);
}
@@ -494,33 +484,13 @@ Address JSTypedArray::ExternalPointerCompensationForOnHeapArray(
#endif
}
-uint32_t JSTypedArray::GetExternalBackingStoreRefForDeserialization() const {
- DCHECK(!is_on_heap());
- return static_cast<uint32_t>(
- ReadField<Address>(offsetof(JSTypedArray, external_pointer_)));
-}
-
-void JSTypedArray::SetExternalBackingStoreRefForSerialization(uint32_t ref) {
- DCHECK(!is_on_heap());
- WriteField<Address>(offsetof(JSTypedArray, external_pointer_),
- static_cast<Address>(ref));
-}
-
-void JSTypedArray::RemoveExternalPointerCompensationForSerialization(
- Isolate* isolate) {
+void JSTypedArray::InitOnHeapDataPtrAfterDeserialization(Isolate* isolate) {
DCHECK(is_on_heap());
+ DCHECK_EQ(external_pointer_.value(), kNullAddress);
Address offset =
- external_pointer() - ExternalPointerCompensationForOnHeapArray(isolate);
- WriteField<Address>(offsetof(JSTypedArray, external_pointer_), offset);
-}
-
-void JSTypedArray::AddExternalPointerCompensationForDeserialization(
- Isolate* isolate) {
- DCHECK(is_on_heap());
- Address pointer =
- ReadField<Address>(offsetof(JSTypedArray, external_pointer_)) +
- ExternalPointerCompensationForOnHeapArray(isolate);
- set_external_pointer(isolate, pointer);
+ OFFSET_OF_DATA_START(ByteArray) - kHeapObjectTag + byte_offset();
+ set_external_pointer(
+ isolate, offset + ExternalPointerCompensationForOnHeapArray(isolate));
}
void* JSTypedArray::DataPtr() {
diff --git a/deps/v8/src/objects/js-array-buffer.cc b/deps/v8/src/objects/js-array-buffer.cc
index 5c44f10c5d2..1007cf56886 100644
--- a/deps/v8/src/objects/js-array-buffer.cc
+++ b/deps/v8/src/objects/js-array-buffer.cc
@@ -4,8 +4,10 @@
#include "src/objects/js-array-buffer.h"
+#include "src/api/api-inl.h"
#include "src/execution/protectors-inl.h"
#include "src/logging/counters.h"
+#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/sandbox/check.h"
@@ -242,6 +244,16 @@ void JSArrayBuffer::DetachInternal(DirectHandle<JSArrayBuffer> array_buffer,
DCHECK(!array_buffer->is_shared());
array_buffer->set_backing_store(isolate, EmptyBackingStoreBuffer());
array_buffer->set_byte_length(0);
+
+ if (isolate->array_buffer_detach_callback() != nullptr) {
+ if (CppHeapObjectWrapper(*array_buffer)
+ .GetCppHeapWrappable(isolate, kAnyCppHeapPointer)) {
+ HandleScope scope(isolate);
+ isolate->array_buffer_detach_callback()(
+ reinterpret_cast<v8::Isolate*>(isolate),
+ Utils::ToLocal(array_buffer));
+ }
+ }
}
void JSArrayBuffer::MakeImmutable(Isolate* isolate) {
diff --git a/deps/v8/src/objects/js-array-buffer.h b/deps/v8/src/objects/js-array-buffer.h
index 0376f9fa508..a63e91d3b98 100644
--- a/deps/v8/src/objects/js-array-buffer.h
+++ b/deps/v8/src/objects/js-array-buffer.h
@@ -189,17 +189,6 @@ V8_OBJECT class JSArrayBuffer : public JSAPIObjectWithEmbedderSlots {
V8_EXPORT_PRIVATE ArrayBufferExtension* CreateExtension(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store);
- //
- // Serializer/deserializer support.
- //
-
- // Backing stores are serialized/deserialized separately. During serialization
- // the backing store reference is stored in the backing store field and upon
- // deserialization it is converted back to actual external (off-heap) pointer
- // value.
- inline uint32_t GetBackingStoreRefForDeserialization() const;
- inline void SetBackingStoreRefForSerialization(uint32_t ref);
-
// Dispatched behavior.
DECL_PRINTER(JSArrayBuffer)
DECL_VERIFIER(JSArrayBuffer)
@@ -564,20 +553,8 @@ V8_OBJECT class JSTypedArray : public JSArrayBufferView {
// Serializer/deserializer support.
//
- // External backing stores are serialized/deserialized separately.
- // During serialization the backing store reference is stored in the typed
- // array object and upon deserialization it is converted back to actual
- // external (off-heap) pointer value.
- // The backing store reference is stored in the external_pointer field.
- inline uint32_t GetExternalBackingStoreRefForDeserialization() const;
- inline void SetExternalBackingStoreRefForSerialization(uint32_t ref);
-
- // Subtracts external pointer compensation from the external pointer value.
- inline void RemoveExternalPointerCompensationForSerialization(
- Isolate* isolate);
- // Adds external pointer compensation to the external pointer value.
- inline void AddExternalPointerCompensationForDeserialization(
- Isolate* isolate);
+ // Initializes the external pointer value for on-heap typed arrays.
+ inline void InitOnHeapDataPtrAfterDeserialization(Isolate* isolate);
static inline MaybeDirectHandle<JSTypedArray> Validate(
Isolate* isolate, DirectHandle<Object> receiver, const char* method_name,
@@ -604,8 +581,6 @@ V8_OBJECT class JSTypedArray : public JSArrayBufferView {
v8::ArrayBufferView::kEmbedderFieldCount > 0;
private:
- template <typename IsolateT>
- friend class Deserializer;
friend class Factory;
inline void set_length(size_t value);
diff --git a/deps/v8/src/objects/js-atomics-synchronization-inl.h b/deps/v8/src/objects/js-atomics-synchronization-inl.h
index c053c39aae2..9b1f508781a 100644
--- a/deps/v8/src/objects/js-atomics-synchronization-inl.h
+++ b/deps/v8/src/objects/js-atomics-synchronization-inl.h
@@ -112,9 +112,11 @@ JSSynchronizationPrimitive::SetWaiterQueueHead(Isolate* requester,
base::AsAtomic32::Release_Store(waiter_queue_head_handle_location(),
handle);
WriteBarrier::ForExternalPointer(
- this, RawExternalPointerField(
- offsetof(JSSynchronizationPrimitive, waiter_queue_head_),
- kWaiterQueueNodeTag));
+ this,
+ RawExternalPointerField(
+ offsetof(JSSynchronizationPrimitive, waiter_queue_head_),
+ kWaiterQueueNodeTag),
+ handle);
return new_state;
}
if (DEBUG_BOOL) {
diff --git a/deps/v8/src/objects/js-collator-inl.h b/deps/v8/src/objects/js-collator-inl.h
index cf4dde66747..4e99e8b5452 100644
--- a/deps/v8/src/objects/js-collator-inl.h
+++ b/deps/v8/src/objects/js-collator-inl.h
@@ -22,11 +22,11 @@
namespace v8 {
namespace internal {
-Tagged<CppGCManaged<icu::Collator>> JSCollator::icu_collator() const {
- return Cast<CppGCManaged<icu::Collator>>(icu_collator_.load());
+Tagged<Managed<icu::Collator>> JSCollator::icu_collator() const {
+ return Cast<Managed<icu::Collator>>(icu_collator_.load());
}
-void JSCollator::set_icu_collator(Tagged<CppGCManaged<icu::Collator>> value,
+void JSCollator::set_icu_collator(Tagged<Managed<icu::Collator>> value,
WriteBarrierMode mode) {
icu_collator_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-collator.cc b/deps/v8/src/objects/js-collator.cc
index 608ee630dff..f70ba1eb5da 100644
--- a/deps/v8/src/objects/js-collator.cc
+++ b/deps/v8/src/objects/js-collator.cc
@@ -91,8 +91,7 @@ DirectHandle<JSObject> JSCollator::ResolvedOptions(
DirectHandle<JSObject> options =
isolate->factory()->NewJSObject(isolate->object_function());
- CppGCManaged<icu::Collator>::Ptr icu_collator =
- collator->icu_collator()->ptr();
+ Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
DCHECK_NOT_NULL(icu_collator);
UErrorCode status = U_ZERO_ERROR;
@@ -574,8 +573,8 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, DirectHandle<Map> map,
DCHECK(U_SUCCESS(status));
}
- DirectHandle<CppGCManaged<icu::Collator>> managed_collator =
- CppGCManaged<icu::Collator>::Create(isolate, 0, std::move(icu_collator));
+ DirectHandle<Managed<icu::Collator>> managed_collator =
+ Managed<icu::Collator>::From(isolate, 0, std::move(icu_collator));
Maybe<std::string> maybe_locale_str = Intl::ToLanguageTag(icu_locale);
MAYBE_RETURN(maybe_locale_str, MaybeHandle<JSCollator>());
diff --git a/deps/v8/src/objects/js-collator.h b/deps/v8/src/objects/js-collator.h
index 0d914ed11d6..f8ae3c967ab 100644
--- a/deps/v8/src/objects/js-collator.h
+++ b/deps/v8/src/objects/js-collator.h
@@ -42,8 +42,8 @@ V8_OBJECT class JSCollator : public JSObject {
V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();
- inline Tagged<CppGCManaged<icu::Collator>> icu_collator() const;
- inline void set_icu_collator(Tagged<CppGCManaged<icu::Collator>> value,
+ inline Tagged<Managed<icu::Collator>> icu_collator() const;
+ inline void set_icu_collator(Tagged<Managed<icu::Collator>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<Undefined, JSFunction>> bound_compare() const;
@@ -60,7 +60,7 @@ V8_OBJECT class JSCollator : public JSObject {
static const int kHeaderSize;
public:
- TaggedMember<CppGCManaged<icu::Collator>> icu_collator_;
+ TaggedMember<Foreign> icu_collator_;
TaggedMember<UnionOf<Undefined, JSFunction>> bound_compare_;
TaggedMember<String> locale_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-collator.tq b/deps/v8/src/objects/js-collator.tq
index 558f07a193c..4abc1b6c5f4 100644
--- a/deps/v8/src/objects/js-collator.tq
+++ b/deps/v8/src/objects/js-collator.tq
@@ -6,7 +6,7 @@
@cppObjectLayoutDefinition
extern class JSCollator extends JSObject {
- icu_collator: CppGCManagedBase; // CppGCManaged<icu::Collator>
+ icu_collator: Foreign; // Managed<icu::Collator>
bound_compare: Undefined|JSFunction;
locale: String;
}
diff --git a/deps/v8/src/objects/js-data-object-builder-inl.h b/deps/v8/src/objects/js-data-object-builder-inl.h
index 5b4a10acca8..48fedddb965 100644
--- a/deps/v8/src/objects/js-data-object-builder-inl.h
+++ b/deps/v8/src/objects/js-data-object-builder-inl.h
@@ -418,7 +418,12 @@ bool JSDataObjectBuilder::TryFastTransitionToPropertyKey(
descriptor_index)),
isolate_);
target_map = expected_final_map_;
- } else {
+ } else if (key_chars.data() != nullptr) {
+ // The byte-compare transition fast path is only valid when `key_chars`
+ // faithfully represent the decoded key. Callers that cannot provide valid
+ // chars (the JSON parser passes an empty vector for escaped keys, whose raw
+ // source bytes differ from the decoded key) fall through to the
+ // decode-then-FindTransitionToField path below.
TransitionsAccessor transitions(isolate_, *map_);
auto expected_transition = transitions.ExpectedTransition(key_chars);
if (!expected_transition.first.is_null()) {
diff --git a/deps/v8/src/objects/js-date-time-format-inl.h b/deps/v8/src/objects/js-date-time-format-inl.h
index 9789cb63899..e74a08904eb 100644
--- a/deps/v8/src/objects/js-date-time-format-inl.h
+++ b/deps/v8/src/objects/js-date-time-format-inl.h
@@ -25,32 +25,30 @@ void JSDateTimeFormat::set_locale(Tagged<String> value, WriteBarrierMode mode) {
locale_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::Locale>> JSDateTimeFormat::icu_locale() const {
- return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
+Tagged<Managed<icu::Locale>> JSDateTimeFormat::icu_locale() const {
+ return Cast<Managed<icu::Locale>>(icu_locale_.load());
}
-void JSDateTimeFormat::set_icu_locale(
- Tagged<CppGCManaged<icu::Locale>> value, WriteBarrierMode mode) {
+void JSDateTimeFormat::set_icu_locale(Tagged<Managed<icu::Locale>> value,
+ WriteBarrierMode mode) {
icu_locale_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::SimpleDateFormat>>
+Tagged<Managed<icu::SimpleDateFormat>>
JSDateTimeFormat::icu_simple_date_format() const {
- return Cast<CppGCManaged<icu::SimpleDateFormat>>(
- icu_simple_date_format_.load());
+ return Cast<Managed<icu::SimpleDateFormat>>(icu_simple_date_format_.load());
}
void JSDateTimeFormat::set_icu_simple_date_format(
- Tagged<CppGCManaged<icu::SimpleDateFormat>> value, WriteBarrierMode mode) {
+ Tagged<Managed<icu::SimpleDateFormat>> value, WriteBarrierMode mode) {
icu_simple_date_format_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::DateIntervalFormat>>
+Tagged<Managed<icu::DateIntervalFormat>>
JSDateTimeFormat::icu_date_interval_format() const {
- return Cast<CppGCManaged<icu::DateIntervalFormat>>(
+ return Cast<Managed<icu::DateIntervalFormat>>(
icu_date_interval_format_.load());
}
void JSDateTimeFormat::set_icu_date_interval_format(
- Tagged<CppGCManaged<icu::DateIntervalFormat>> value,
- WriteBarrierMode mode) {
+ Tagged<Managed<icu::DateIntervalFormat>> value, WriteBarrierMode mode) {
icu_date_interval_format_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-date-time-format.cc b/deps/v8/src/objects/js-date-time-format.cc
index e144c1bd33d..05999c6ad9f 100644
--- a/deps/v8/src/objects/js-date-time-format.cc
+++ b/deps/v8/src/objects/js-date-time-format.cc
@@ -9,6 +9,7 @@
#include <memory>
#include <optional>
#include <string>
+#include <string_view>
#include <utility>
#include <vector>
@@ -473,7 +474,7 @@ std::string ToTitleCaseTimezoneLocation(const std::string& input) {
// Special case Au/Es/Of to be lower case.
if (word_length == 2) {
size_t pos = title_cased.length() - 2;
- std::string substr = title_cased.substr(pos, 2);
+ std::string_view substr = std::string_view(title_cased).substr(pos, 2);
if (substr == "Of" || substr == "Es" || substr == "Au") {
title_cased[pos] = LocaleIndependentAsciiToLower(title_cased[pos]);
}
@@ -684,11 +685,10 @@ MaybeDirectHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
DirectHandle<String> locale(date_time_format->locale(), isolate);
DCHECK(!date_time_format->icu_locale().is_null());
- CppGCManaged<icu::Locale>::Ptr icu_locale =
- date_time_format->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = date_time_format->icu_locale()->ptr();
DCHECK_NOT_NULL(icu_locale);
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
date_time_format->icu_simple_date_format()->ptr();
DirectHandle<Object> timezone =
JSDateTimeFormat::TimeZone(isolate, date_time_format);
@@ -1002,7 +1002,7 @@ template <typename T>
Maybe<DateTimeValueRecord> HandleDateTimeTemporalGeneric(
Isolate* isolate, DirectHandle<JSDateTimeFormat> date_time_format,
PatternKind kind, DirectHandle<T> temporal) {
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
date_time_format->icu_simple_date_format()->ptr();
// Onlt perform this check for calendared types (not Time)
@@ -1231,7 +1231,7 @@ Maybe<DateTimeValueRecord> HandleDateTimeValue(
return HandleDateTimeOthers(isolate, date_time_format, x, method_name);
}
-char16_t EqualventSkeletonchar(char16_t in) {
+char16_t EquivalentSkeletonChar(char16_t in) {
switch (in) {
case 'L':
return 'M';
@@ -1247,6 +1247,10 @@ char16_t EqualventSkeletonchar(char16_t in) {
return 'z';
case 'v':
return 'z';
+ case 'r':
+ return 'y';
+ case 'U':
+ return 'y';
default:
return '\0';
}
@@ -1257,7 +1261,7 @@ icu::UnicodeString AdjustDateTimeStyleFormat(
const std::set<char16_t>& allowed_options) {
std::set<char16_t> allowed(allowed_options);
for (int ch : allowed_options) {
- auto also = EqualventSkeletonchar(ch);
+ auto also = EquivalentSkeletonChar(ch);
if (also) {
allowed.emplace(also);
}
@@ -1349,7 +1353,7 @@ icu::UnicodeString GetDateTimeFormat(const icu::UnicodeString& options,
char16_t ch = options.charAt(i);
if (required_options.find(ch) != required_options.end()) {
to_be_added.erase(ch);
- auto also = EqualventSkeletonchar(ch);
+ auto also = EquivalentSkeletonChar(ch);
if (also) {
to_be_added.erase(also);
}
@@ -1400,6 +1404,9 @@ std::set<char16_t> ExplicitComponentsSet(int32_t components) {
}
if (Year::decode(components)) {
result.insert('y');
+ result.insert('r');
+ result.insert('U');
+ result.insert('G');
}
if (Month::decode(components)) {
result.insert('M');
@@ -1491,7 +1498,7 @@ icu::UnicodeString GetSkeletonForPatternKind(
best_format,
// Allowed options: [[weekday]], [[era]], [[year]], [[month]],
// [[day]]
- {'E', 'c', 'G', 'y', 'M', 'L', 'd'});
+ {'E', 'c', 'G', 'y', 'r', 'U', 'M', 'L', 'd'});
}
// ii. Set dateTimeFormat.[[TemporalPlainYearMonthFormat]] to
// AdjustDateTimeStyleFormat(formats, bestFormat, formatMatcher, «
@@ -1502,7 +1509,7 @@ icu::UnicodeString GetSkeletonForPatternKind(
// [[era]], [[year]], [[month]] »).
return AdjustDateTimeStyleFormat(best_format,
// Allowed options: [[year]], [[month]]
- {'G', 'y', 'M', 'L'});
+ {'G', 'y', 'r', 'U', 'M', 'L'});
}
if (kind == PatternKind::kPlainMonthDay) {
// iii. Set dateTimeFormat.[[TemporalPlainMonthDayFormat]] to
@@ -1540,8 +1547,8 @@ icu::UnicodeString GetSkeletonForPatternKind(
// [[weekday]], [[era]], [[year]], [[month]],
// [[day]], [[hour]], [[minute]], [[second]], [[dayPeriod]],
// [[fractionalSecondDigits]]
- {'E', 'c', 'G', 'y', 'M', 'L', 'd', 'h', 'H', 'k', 'K', 'j', 'm',
- 's', 'B', 'b', 'a', 'S'});
+ {'E', 'c', 'G', 'y', 'r', 'U', 'M', 'L', 'd', 'h', 'H', 'k', 'K',
+ 'j', 'm', 's', 'B', 'b', 'a', 'S'});
case PatternKind::kInstant:
// k. Set dateTimeFormat.[[TemporalInstantFormat]] to bestFormat.
return best_format;
@@ -1556,7 +1563,7 @@ icu::UnicodeString GetSkeletonForPatternKind(
// b. Let requiredOptions be « "weekday", "year", "month", "day",
// "dayPeriod", "hour", "minute", "second", "fractionalSecondDigits" ».
static const std::initializer_list<char16_t> kRequiredAny{
- 'E', 'c', 'G', 'y', 'M', 'L', 'd', 'h', 'H',
+ 'E', 'c', 'G', 'y', 'r', 'U', 'M', 'L', 'd', 'h', 'H',
'k', 'K', 'j', 'm', 's', 'B', 'b', 'a', 'S'};
// 10. Else,
// a. Assert: defaults is zoned-date-time or all.
@@ -1571,7 +1578,7 @@ icu::UnicodeString GetSkeletonForPatternKind(
// const std::set<char16_t> kRequireddate({{'E', 'c', 'G', 'y', 'M',
// 'L', 'd'}});
static const std::initializer_list<char16_t> kRequiredDate{
- 'E', 'c', 'G', 'y', 'M', 'L', 'd'};
+ 'E', 'c', 'G', 'y', 'r', 'U', 'M', 'L', 'd'};
// 6. If defaults is date, then
// a. Let defaultOptions be « "year", "month", "day" ».
static const std::initializer_list<char16_t> kDefaultsDate{'y', 'M',
@@ -1588,7 +1595,7 @@ icu::UnicodeString GetSkeletonForPatternKind(
// 3. Else if required is year-month, then
// a. Let requiredOptions be « "year", "month" ».
static const std::initializer_list<char16_t> kRequiredYearMonth{
- 'G', 'y', 'M', 'L'};
+ 'G', 'y', 'r', 'U', 'M', 'L'};
// 8. Else if defaults is year-month, then
// a. Let defaultOptions be « "year", "month" ».
static const std::initializer_list<char16_t> kDefaultsYearMonth{'y',
@@ -1793,7 +1800,7 @@ MaybeDirectHandle<String> FormatDateTime(
MaybeDirectHandle<String> FormatMillisecondsByKindToString(
Isolate* isolate, DirectHandle<JSDateTimeFormat> date_time_format,
DirectHandle<Object> value, PatternKind kind, bool is_plain, double x) {
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
date_time_format->icu_simple_date_format()->ptr();
UErrorCode status = U_ZERO_ERROR;
std::optional<icu::UnicodeString> result = CallICUFormat(
@@ -1849,7 +1856,7 @@ MaybeDirectHandle<String> JSDateTimeFormat::DateTimeFormat(
x = Object::NumberValue(*date);
}
// 5. Return FormatDateTime(dtf, x).
- CppGCManaged<icu::SimpleDateFormat>::Ptr format =
+ Managed<icu::SimpleDateFormat>::Ptr format =
date_time_format->icu_simple_date_format()->ptr();
return FormatDateTime(isolate, *format, x);
}
@@ -1919,7 +1926,7 @@ MaybeDirectHandle<String> JSDateTimeFormat::ToLocaleDateTime(
JSDateTimeFormat::CreateDateTimeFormat(
isolate, map, locales, options, required, defaults, {}, method_name));
- CppGCManaged<icu::SimpleDateFormat>::Ptr format =
+ Managed<icu::SimpleDateFormat>::Ptr format =
date_time_format->icu_simple_date_format()->ptr();
if (can_cache) {
isolate->set_icu_object_in_cache(cache_type, locales,
@@ -2346,7 +2353,7 @@ std::unique_ptr<icu::DateIntervalFormat> LazyCreateDateIntervalFormat(
loc.setUnicodeKeywordValue("hc", hcString, status);
}
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
date_time_format->icu_simple_date_format()->ptr();
icu::UnicodeString skeleton = GetSkeletonForPatternKind(
@@ -2361,9 +2368,9 @@ std::unique_ptr<icu::DateIntervalFormat> LazyCreateDateIntervalFormat(
if (kind != PatternKind::kDate) {
return date_interval_format;
}
- DirectHandle<CppGCManaged<icu::DateIntervalFormat>> managed_interval_format =
- CppGCManaged<icu::DateIntervalFormat>::Create(
- isolate, 0, std::move(date_interval_format));
+ DirectHandle<Managed<icu::DateIntervalFormat>> managed_interval_format =
+ Managed<icu::DateIntervalFormat>::From(isolate, 0,
+ std::move(date_interval_format));
date_time_format->set_icu_date_interval_format(*managed_interval_format);
DisallowGarbageCollection no_gc;
@@ -3081,16 +3088,16 @@ MaybeDirectHandle<JSDateTimeFormat> JSDateTimeFormat::CreateDateTimeFormat(
isolate->factory()->NewStringFromAsciiChecked(
maybe_locale_str.FromJust().c_str());
- DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
- CppGCManaged<icu::Locale>::Create(
+ DirectHandle<Managed<icu::Locale>> managed_locale =
+ Managed<icu::Locale>::From(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
- DirectHandle<CppGCManaged<icu::SimpleDateFormat>> managed_format =
- CppGCManaged<icu::SimpleDateFormat>::Create(isolate, 0,
- std::move(icu_date_format));
+ DirectHandle<Managed<icu::SimpleDateFormat>> managed_format =
+ Managed<icu::SimpleDateFormat>::From(isolate, 0,
+ std::move(icu_date_format));
- DirectHandle<CppGCManaged<icu::DateIntervalFormat>> managed_interval_format =
- CppGCManaged<icu::DateIntervalFormat>::Create(isolate, 0, nullptr);
+ DirectHandle<Managed<icu::DateIntervalFormat>> managed_interval_format =
+ Managed<icu::DateIntervalFormat>::From(isolate, 0, nullptr);
// Now all properties are ready, so we can allocate the result object.
DirectHandle<JSDateTimeFormat> date_time_format = Cast<JSDateTimeFormat>(
@@ -3188,7 +3195,7 @@ MaybeDirectHandle<JSArray> FormatMillisecondsByKindToArray(
bool output_source) {
icu::FieldPositionIterator fp_iter;
UErrorCode status = U_ZERO_ERROR;
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
date_time_format->icu_simple_date_format()->ptr();
auto formatted = CallICUFormat(
*icu_date_format, date_time_format->explicit_components_in_options(),
@@ -3493,7 +3500,7 @@ std::optional<MaybeDirectHandle<T>> PartitionDateTimeRangePattern(
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError));
}
- CppGCManaged<icu::SimpleDateFormat>::Ptr date_format =
+ Managed<icu::SimpleDateFormat>::Ptr date_format =
date_time_format->icu_simple_date_format()->ptr();
const icu::Calendar* calendar = date_format->getCalendar();
@@ -3587,7 +3594,7 @@ MaybeDirectHandle<T> FormatRangeCommonWithTemporalSupport(
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError));
}
- CppGCManaged<icu::SimpleDateFormat>::Ptr icu_date_format =
+ Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
date_time_format->icu_simple_date_format()->ptr();
// 17. Assert: xFormatRecord.[[IsPlain]] = yFormatRecord.[[IsPlain]].
diff --git a/deps/v8/src/objects/js-date-time-format.h b/deps/v8/src/objects/js-date-time-format.h
index 4af5c0691dd..700c2e97366 100644
--- a/deps/v8/src/objects/js-date-time-format.h
+++ b/deps/v8/src/objects/js-date-time-format.h
@@ -168,20 +168,19 @@ V8_OBJECT class JSDateTimeFormat : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
+ inline Tagged<Managed<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::SimpleDateFormat>> icu_simple_date_format()
- const;
+ inline Tagged<Managed<icu::SimpleDateFormat>> icu_simple_date_format() const;
inline void set_icu_simple_date_format(
- Tagged<CppGCManaged<icu::SimpleDateFormat>> value,
+ Tagged<Managed<icu::SimpleDateFormat>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::DateIntervalFormat>>
- icu_date_interval_format() const;
+ inline Tagged<Managed<icu::DateIntervalFormat>> icu_date_interval_format()
+ const;
inline void set_icu_date_interval_format(
- Tagged<CppGCManaged<icu::DateIntervalFormat>> value,
+ Tagged<Managed<icu::DateIntervalFormat>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<JSFunction, Undefined>> bound_format() const;
@@ -202,9 +201,9 @@ V8_OBJECT class JSDateTimeFormat : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<CppGCManaged<icu::Locale>> icu_locale_;
- TaggedMember<CppGCManaged<icu::SimpleDateFormat>> icu_simple_date_format_;
- TaggedMember<CppGCManaged<icu::DateIntervalFormat>> icu_date_interval_format_;
+ TaggedMember<Foreign> icu_locale_;
+ TaggedMember<Foreign> icu_simple_date_format_;
+ TaggedMember<Foreign> icu_date_interval_format_;
TaggedMember<UnionOf<JSFunction, Undefined>> bound_format_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-date-time-format.tq b/deps/v8/src/objects/js-date-time-format.tq
index 3bf82fdc066..5ca6d8c2f40 100644
--- a/deps/v8/src/objects/js-date-time-format.tq
+++ b/deps/v8/src/objects/js-date-time-format.tq
@@ -20,11 +20,9 @@ bitfield struct JSDateTimeFormatFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSDateTimeFormat extends JSObject {
locale: String;
- icu_locale: CppGCManagedBase; // CppGCManaged<icu::Locale>
- icu_simple_date_format:
- CppGCManagedBase; // CppGCManaged<icu::SimpleDateFormat>
- icu_date_interval_format:
- CppGCManagedBase; // CppGCManaged<icu::DateIntervalFormat>
+ icu_locale: Foreign; // Managed<icu::Locale>
+ icu_simple_date_format: Foreign; // Managed<icu::SimpleDateFormat>
+ icu_date_interval_format: Foreign; // Managed<icu::DateIntervalFormat>
bound_format: JSFunction|Undefined;
flags: SmiTagged<JSDateTimeFormatFlags>;
}
diff --git a/deps/v8/src/objects/js-duration-format-inl.h b/deps/v8/src/objects/js-duration-format-inl.h
index b016df321dd..d8f785d1575 100644
--- a/deps/v8/src/objects/js-duration-format-inl.h
+++ b/deps/v8/src/objects/js-duration-format-inl.h
@@ -34,11 +34,11 @@ void JSDurationFormat::set_display_flags(int value) {
display_flags_.store(this, Smi::FromInt(value));
}
-Tagged<CppGCManaged<icu::Locale>> JSDurationFormat::icu_locale() const {
- return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
+Tagged<Managed<icu::Locale>> JSDurationFormat::icu_locale() const {
+ return Cast<Managed<icu::Locale>>(icu_locale_.load());
}
-void JSDurationFormat::set_icu_locale(
- Tagged<CppGCManaged<icu::Locale>> value, WriteBarrierMode mode) {
+void JSDurationFormat::set_icu_locale(Tagged<Managed<icu::Locale>> value,
+ WriteBarrierMode mode) {
icu_locale_.store(this, value, mode);
}
@@ -111,13 +111,13 @@ inline int32_t JSDurationFormat::fractional_digits() const {
return v;
}
-Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+Tagged<Managed<icu::number::LocalizedNumberFormatter>>
JSDurationFormat::icu_number_formatter() const {
- return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
+ return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSDurationFormat::set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode) {
icu_number_formatter_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-duration-format.cc b/deps/v8/src/objects/js-duration-format.cc
index 4b42cc49c3a..36458e43cb0 100644
--- a/deps/v8/src/objects/js-duration-format.cc
+++ b/deps/v8/src/objects/js-duration-format.cc
@@ -333,8 +333,8 @@ MaybeDirectHandle<JSDurationFormat> JSDurationFormat::New(
// 14. Set durationFormat.[[Style]] to style.
// 15. Set durationFormat.[[DataLocale]] to r.[[dataLocale]].
- DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
- CppGCManaged<icu::Locale>::Create(
+ DirectHandle<Managed<icu::Locale>> managed_locale =
+ Managed<icu::Locale>::From(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
// 16. Let prevStyle be the empty String.
// 17. For each row of Table 1, except the header row, in table order, do
@@ -449,9 +449,9 @@ MaybeDirectHandle<JSDurationFormat> JSDurationFormat::New(
numbering_system.c_str(), status));
DCHECK(U_SUCCESS(status));
}
- DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<Managed<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
+ Managed<icu::number::LocalizedNumberFormatter>::From(
isolate, 0,
std::make_shared<icu::number::LocalizedNumberFormatter>(fmt));
diff --git a/deps/v8/src/objects/js-duration-format.h b/deps/v8/src/objects/js-duration-format.h
index fad50ad3499..ca42ec1c886 100644
--- a/deps/v8/src/objects/js-duration-format.h
+++ b/deps/v8/src/objects/js-duration-format.h
@@ -209,14 +209,14 @@ V8_OBJECT class JSDurationFormat : public JSObject {
inline int display_flags() const;
inline void set_display_flags(int value);
- inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
+ inline Tagged<Managed<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<Managed<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSDurationFormat)
@@ -227,9 +227,8 @@ V8_OBJECT class JSDurationFormat : public JSObject {
public:
TaggedMember<Smi> style_flags_;
TaggedMember<Smi> display_flags_;
- TaggedMember<CppGCManaged<icu::Locale>> icu_locale_;
- TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
- icu_number_formatter_;
+ TaggedMember<Foreign> icu_locale_;
+ TaggedMember<Foreign> icu_number_formatter_;
} V8_OBJECT_END;
inline constexpr int JSDurationFormat::kHeaderSize = sizeof(JSDurationFormat);
diff --git a/deps/v8/src/objects/js-duration-format.tq b/deps/v8/src/objects/js-duration-format.tq
index 5e47435afb9..d43c4b0e3a4 100644
--- a/deps/v8/src/objects/js-duration-format.tq
+++ b/deps/v8/src/objects/js-duration-format.tq
@@ -46,7 +46,7 @@ bitfield struct JSDurationFormatDisplayFlags extends uint31 {
extern class JSDurationFormat extends JSObject {
style_flags: SmiTagged<JSDurationFormatStyleFlags>;
display_flags: SmiTagged<JSDurationFormatDisplayFlags>;
- icu_locale: CppGCManagedBase; // CppGCManaged<icu::Locale>
+ icu_locale: Foreign; // Managed<icu::Locale>
icu_number_formatter:
- CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
+ Foreign; // Managed<icu::number::LocalizedNumberFormatter>
}
diff --git a/deps/v8/src/objects/js-function.cc b/deps/v8/src/objects/js-function.cc
index 63423bfe127..585d97d436c 100644
--- a/deps/v8/src/objects/js-function.cc
+++ b/deps/v8/src/objects/js-function.cc
@@ -1415,7 +1415,7 @@ DirectHandle<String> JSFunction::GetDebugName(
// that exact behavior and go with SharedFunctionInfo::DebugName()
// in case of the fast-path.
DirectHandle<Object> name = JSReceiver::GetDataProperty(
- isolate, function, isolate->factory()->name_string());
+ isolate, function, isolate->factory()->name_string(), allow_allocation);
if (IsString(*name)) return Cast<String>(name);
}
return SharedFunctionInfo::DebugName(
diff --git a/deps/v8/src/objects/js-list-format-inl.h b/deps/v8/src/objects/js-list-format-inl.h
index 925d421a784..fef695de69d 100644
--- a/deps/v8/src/objects/js-list-format-inl.h
+++ b/deps/v8/src/objects/js-list-format-inl.h
@@ -25,11 +25,11 @@ void JSListFormat::set_locale(Tagged<String> value, WriteBarrierMode mode) {
locale_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::ListFormatter>> JSListFormat::icu_formatter() const {
- return Cast<CppGCManaged<icu::ListFormatter>>(icu_formatter_.load());
+Tagged<Managed<icu::ListFormatter>> JSListFormat::icu_formatter() const {
+ return Cast<Managed<icu::ListFormatter>>(icu_formatter_.load());
}
-void JSListFormat::set_icu_formatter(
- Tagged<CppGCManaged<icu::ListFormatter>> value, WriteBarrierMode mode) {
+void JSListFormat::set_icu_formatter(Tagged<Managed<icu::ListFormatter>> value,
+ WriteBarrierMode mode) {
icu_formatter_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-list-format.cc b/deps/v8/src/objects/js-list-format.cc
index 6257491fc07..da6e33abcd7 100644
--- a/deps/v8/src/objects/js-list-format.cc
+++ b/deps/v8/src/objects/js-list-format.cc
@@ -125,9 +125,8 @@ MaybeDirectHandle<JSListFormat> JSListFormat::New(
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
}
- DirectHandle<CppGCManaged<icu::ListFormatter>> managed_formatter =
- CppGCManaged<icu::ListFormatter>::Create(isolate, 0,
- std::move(formatter));
+ DirectHandle<Managed<icu::ListFormatter>> managed_formatter =
+ Managed<icu::ListFormatter>::From(isolate, 0, std::move(formatter));
// Now all properties are ready, so we can allocate the result object.
DirectHandle<JSListFormat> list_format =
@@ -226,8 +225,7 @@ MaybeDirectHandle<T> FormatListCommon(
MAYBE_RETURN(maybe_array, DirectHandle<T>());
std::vector<icu::UnicodeString> array = maybe_array.FromJust();
- CppGCManaged<icu::ListFormatter>::Ptr formatter =
- format->icu_formatter()->ptr();
+ Managed<icu::ListFormatter>::Ptr formatter = format->icu_formatter()->ptr();
DCHECK_NOT_NULL(formatter);
UErrorCode status = U_ZERO_ERROR;
diff --git a/deps/v8/src/objects/js-list-format.h b/deps/v8/src/objects/js-list-format.h
index 5d7cd57350c..c4ea672eeb7 100644
--- a/deps/v8/src/objects/js-list-format.h
+++ b/deps/v8/src/objects/js-list-format.h
@@ -62,8 +62,8 @@ V8_OBJECT class JSListFormat : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::ListFormatter>> icu_formatter() const;
- inline void set_icu_formatter(Tagged<CppGCManaged<icu::ListFormatter>> value,
+ inline Tagged<Managed<icu::ListFormatter>> icu_formatter() const;
+ inline void set_icu_formatter(Tagged<Managed<icu::ListFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int flags() const;
@@ -109,7 +109,7 @@ V8_OBJECT class JSListFormat : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<CppGCManaged<icu::ListFormatter>> icu_formatter_;
+ TaggedMember<Foreign> icu_formatter_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-list-format.tq b/deps/v8/src/objects/js-list-format.tq
index 80ac3757af6..ba8256c07d4 100644
--- a/deps/v8/src/objects/js-list-format.tq
+++ b/deps/v8/src/objects/js-list-format.tq
@@ -15,6 +15,6 @@ bitfield struct JSListFormatFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSListFormat extends JSObject {
locale: String;
- icu_formatter: CppGCManagedBase; // CppGCManaged<icu::ListFormatter>
+ icu_formatter: Foreign; // Managed<icu::ListFormatter>
flags: SmiTagged<JSListFormatFlags>;
}
diff --git a/deps/v8/src/objects/js-locale-inl.h b/deps/v8/src/objects/js-locale-inl.h
index 555f18821a8..87953ea807e 100644
--- a/deps/v8/src/objects/js-locale-inl.h
+++ b/deps/v8/src/objects/js-locale-inl.h
@@ -21,11 +21,11 @@
namespace v8 {
namespace internal {
-Tagged<CppGCManaged<icu::Locale>> JSLocale::icu_locale() const {
- return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
+Tagged<Managed<icu::Locale>> JSLocale::icu_locale() const {
+ return Cast<Managed<icu::Locale>>(icu_locale_.load());
}
-void JSLocale::set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
+void JSLocale::set_icu_locale(Tagged<Managed<icu::Locale>> value,
WriteBarrierMode mode) {
icu_locale_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-locale.cc b/deps/v8/src/objects/js-locale.cc
index a1d67754f48..35b1919f3fb 100644
--- a/deps/v8/src/objects/js-locale.cc
+++ b/deps/v8/src/objects/js-locale.cc
@@ -147,7 +147,7 @@ Maybe<bool> InsertOptionsIntoLocale(Isolate* isolate,
DirectHandle<Object> UnicodeKeywordValue(Isolate* isolate,
DirectHandle<JSLocale> locale,
const char* key) {
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
UErrorCode status = U_ZERO_ERROR;
std::string value =
icu_locale->getUnicodeKeywordValue<std::string>(key, status);
@@ -477,8 +477,8 @@ MaybeDirectHandle<JSLocale> JSLocale::New(Isolate* isolate,
}
// 31. Set locale.[[Locale]] to r.[[locale]].
- DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
- CppGCManaged<icu::Locale>::Create(
+ DirectHandle<Managed<icu::Locale>> managed_locale =
+ Managed<icu::Locale>::From(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
// Now all properties are ready, so we can allocate the result object.
@@ -493,8 +493,8 @@ namespace {
MaybeDirectHandle<JSLocale> Construct(Isolate* isolate,
const icu::Locale& icu_locale) {
- DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
- CppGCManaged<icu::Locale>::Create(
+ DirectHandle<Managed<icu::Locale>> managed_locale =
+ Managed<icu::Locale>::From(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
DirectHandle<JSFunction> constructor(
@@ -974,7 +974,7 @@ MaybeDirectHandle<JSObject> JSLocale::GetWeekInfo(
DirectHandle<Object> JSLocale::Language(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
const char* language = icu_locale->getLanguage();
constexpr const char kUnd[] = "und";
if (strlen(language) == 0) {
@@ -986,7 +986,7 @@ DirectHandle<Object> JSLocale::Language(Isolate* isolate,
DirectHandle<Object> JSLocale::Script(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
const char* script = icu_locale->getScript();
if (strlen(script) == 0) return factory->undefined_value();
return factory->NewStringFromAsciiChecked(script);
@@ -1011,7 +1011,7 @@ DirectHandle<Object> JSLocale::Variants(Isolate* isolate,
DirectHandle<Object> JSLocale::Region(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
const char* region = icu_locale->getCountry();
if (strlen(region) == 0) return factory->undefined_value();
return factory->NewStringFromAsciiChecked(region);
@@ -1052,7 +1052,7 @@ DirectHandle<Object> JSLocale::HourCycle(Isolate* isolate,
DirectHandle<Object> JSLocale::Numeric(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
UErrorCode status = U_ZERO_ERROR;
std::string numeric =
icu_locale->getUnicodeKeywordValue<std::string>("kn", status);
@@ -1065,7 +1065,7 @@ DirectHandle<Object> JSLocale::NumberingSystem(Isolate* isolate,
}
std::string JSLocale::ToString(DirectHandle<JSLocale> locale) {
- CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
return Intl::ToLanguageTag(*icu_locale).FromJust();
}
diff --git a/deps/v8/src/objects/js-locale.h b/deps/v8/src/objects/js-locale.h
index 28649bd4fcd..bfb79ba1bf4 100644
--- a/deps/v8/src/objects/js-locale.h
+++ b/deps/v8/src/objects/js-locale.h
@@ -92,8 +92,8 @@ V8_OBJECT class JSLocale : public JSObject {
// Help function to check well-formed "3alpha"
static bool Is3Alpha(std::string_view value);
- inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
+ inline Tagged<Managed<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSLocale)
@@ -102,7 +102,7 @@ V8_OBJECT class JSLocale : public JSObject {
static const int kHeaderSize;
public:
- TaggedMember<CppGCManaged<icu::Locale>> icu_locale_;
+ TaggedMember<Foreign> icu_locale_;
} V8_OBJECT_END;
inline constexpr int JSLocale::kHeaderSize = sizeof(JSLocale);
diff --git a/deps/v8/src/objects/js-locale.tq b/deps/v8/src/objects/js-locale.tq
index f46665fcb58..60c97710856 100644
--- a/deps/v8/src/objects/js-locale.tq
+++ b/deps/v8/src/objects/js-locale.tq
@@ -6,5 +6,5 @@
@cppObjectLayoutDefinition
extern class JSLocale extends JSObject {
- icu_locale: CppGCManagedBase; // CppGCManaged<icu::Locale>
+ icu_locale: Foreign; // Managed<icu::Locale>
}
diff --git a/deps/v8/src/objects/js-number-format-inl.h b/deps/v8/src/objects/js-number-format-inl.h
index 31e99afaf0b..2a14788a33d 100644
--- a/deps/v8/src/objects/js-number-format-inl.h
+++ b/deps/v8/src/objects/js-number-format-inl.h
@@ -25,13 +25,13 @@ void JSNumberFormat::set_locale(Tagged<String> value, WriteBarrierMode mode) {
locale_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+Tagged<Managed<icu::number::LocalizedNumberFormatter>>
JSNumberFormat::icu_number_formatter() const {
- return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
+ return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSNumberFormat::set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode) {
icu_number_formatter_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-number-format.cc b/deps/v8/src/objects/js-number-format.cc
index 63b56481563..f772782e640 100644
--- a/deps/v8/src/objects/js-number-format.cc
+++ b/deps/v8/src/objects/js-number-format.cc
@@ -425,13 +425,12 @@ const icu::UnicodeString CurrencyFromSkeleton(
const icu::UnicodeString JSNumberFormat::NumberingSystemFromSkeleton(
const icu::UnicodeString& skeleton) {
const char numbering_system[] = "numbering-system/";
- int32_t index = skeleton.indexOf(numbering_system);
- if (index < 0) return "latn";
- index += static_cast<int32_t>(std::strlen(numbering_system));
- const icu::UnicodeString res = skeleton.tempSubString(index);
- index = res.indexOf(" ");
- if (index < 0) return res;
- return res.tempSubString(0, index);
+ int32_t begin = skeleton.indexOf(numbering_system);
+ if (begin < 0) return "latn";
+ begin += static_cast<int32_t>(std::strlen(numbering_system));
+ int32_t end = skeleton.indexOf(" ", begin);
+ return end <= begin ? skeleton.tempSubString(begin)
+ : skeleton.tempSubStringBetween(begin, end);
}
namespace {
@@ -877,7 +876,7 @@ DirectHandle<JSObject> JSNumberFormat::ResolvedOptions(
Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr fmt =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr fmt =
number_format->icu_number_formatter()->ptr();
icu::UnicodeString skeleton = fmt->toSkeleton(status);
DCHECK(U_SUCCESS(status));
@@ -1463,9 +1462,9 @@ MaybeDirectHandle<JSNumberFormat> JSNumberFormat::New(
//
icu::number::LocalizedNumberFormatter fmt = settings.locale(icu_locale);
- DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<Managed<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
+ Managed<icu::number::LocalizedNumberFormatter>::From(
isolate, 0,
std::make_shared<icu::number::LocalizedNumberFormatter>(fmt));
@@ -2020,7 +2019,7 @@ MaybeDirectHandle<T> PartitionNumberRangePattern(
factory->NewStringFromStaticChars("end"), end));
}
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
number_format->icu_number_formatter()->ptr();
Maybe<icu::number::LocalizedNumberRangeFormatter> maybe_range_formatter =
@@ -2122,7 +2121,7 @@ MaybeDirectHandle<String> JSNumberFormat::NumberFormatFunction(
IntlMathematicalValue::From(isolate, value));
// 5. Return FormatNumeric(nf, x).
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
number_format->icu_number_formatter()->ptr();
Maybe<icu::number::FormattedNumber> maybe_formatted =
IntlMathematicalValue::FormatNumeric(isolate, lfmt.raw(), x);
@@ -2140,7 +2139,7 @@ MaybeDirectHandle<JSArray> JSNumberFormat::FormatToParts(
ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
IntlMathematicalValue::From(isolate, numeric_obj));
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
number_format->icu_number_formatter()->ptr();
Maybe<icu::number::FormattedNumber> maybe_formatted =
IntlMathematicalValue::FormatNumeric(isolate, lfmt.raw(), value);
diff --git a/deps/v8/src/objects/js-number-format.h b/deps/v8/src/objects/js-number-format.h
index 64dea2e4b76..6cd8138359a 100644
--- a/deps/v8/src/objects/js-number-format.h
+++ b/deps/v8/src/objects/js-number-format.h
@@ -116,10 +116,10 @@ V8_OBJECT class JSNumberFormat : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<Managed<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<JSFunction, Undefined>> bound_format() const;
@@ -130,8 +130,7 @@ V8_OBJECT class JSNumberFormat : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
- icu_number_formatter_;
+ TaggedMember<Foreign> icu_number_formatter_;
TaggedMember<UnionOf<JSFunction, Undefined>> bound_format_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-number-format.tq b/deps/v8/src/objects/js-number-format.tq
index a17c1d63de2..59f29cdd34b 100644
--- a/deps/v8/src/objects/js-number-format.tq
+++ b/deps/v8/src/objects/js-number-format.tq
@@ -8,6 +8,6 @@
extern class JSNumberFormat extends JSObject {
locale: String;
icu_number_formatter:
- CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
+ Foreign; // Managed<icu::number::LocalizedNumberFormatter>
bound_format: JSFunction|Undefined;
}
diff --git a/deps/v8/src/objects/js-objects-inl.h b/deps/v8/src/objects/js-objects-inl.h
index 91024ca2577..c715995c87f 100644
--- a/deps/v8/src/objects/js-objects-inl.h
+++ b/deps/v8/src/objects/js-objects-inl.h
@@ -75,11 +75,12 @@ MaybeHandle<Object> JSReceiver::GetElement(Isolate* isolate,
Handle<Object> JSReceiver::GetDataProperty(Isolate* isolate,
DirectHandle<JSReceiver> object,
- DirectHandle<Name> name) {
+ DirectHandle<Name> name,
+ AllowAllocation allow_allocation) {
LookupIterator it(isolate, object, name, object,
LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
if (!it.IsFound()) return it.factory()->undefined_value();
- return GetDataProperty(&it);
+ return GetDataProperty(&it, allow_allocation);
}
MaybeDirectHandle<JSPrototype> JSReceiver::GetPrototype(
diff --git a/deps/v8/src/objects/js-objects.cc b/deps/v8/src/objects/js-objects.cc
index 8b04c8ab5b7..69e7d3101a5 100644
--- a/deps/v8/src/objects/js-objects.cc
+++ b/deps/v8/src/objects/js-objects.cc
@@ -197,7 +197,7 @@ Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it,
auto accessors = it->GetAccessors();
// Special handling for AccessorInfo, which behaves like a data
// property.
- if (IsAccessorInfo(*accessors)) {
+ if (allow_allocation && IsAccessorInfo(*accessors)) {
auto info = Cast<AccessorInfo>(*accessors);
if (info->getter_side_effect_type() ==
SideEffectType::kHasNoSideEffect) {
@@ -5977,7 +5977,7 @@ Tagged<Object> JSDate::GetUTCField(FieldIndex index, double value,
int64_t time_ms = static_cast<int64_t>(value);
if (index == kTimezoneOffset) {
- return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
+ return Smi::FromInt(date_cache->TimezoneOffsetMs(time_ms));
}
int days = DateCache::DaysFromTime(time_ms);
diff --git a/deps/v8/src/objects/js-objects.h b/deps/v8/src/objects/js-objects.h
index bc9e3d6b80f..558c0723146 100644
--- a/deps/v8/src/objects/js-objects.h
+++ b/deps/v8/src/objects/js-objects.h
@@ -329,9 +329,10 @@ V8_OBJECT class JSReceiver : public HeapObject {
DirectHandle<Object> value, bool from_javascript,
ShouldThrow should_throw);
- inline static Handle<Object> GetDataProperty(Isolate* isolate,
- DirectHandle<JSReceiver> object,
- DirectHandle<Name> name);
+ inline static Handle<Object> GetDataProperty(
+ Isolate* isolate, DirectHandle<JSReceiver> object,
+ DirectHandle<Name> name,
+ AllowAllocation allow_allocation = AllowAllocation{true});
V8_EXPORT_PRIVATE static Handle<Object> GetDataProperty(
LookupIterator* it,
AllowAllocation allow_allocation = AllowAllocation{true});
@@ -1413,6 +1414,7 @@ V8_OBJECT class JSDate : public JSObject {
kMillisecondUTC,
kDaysUTC,
kTimeInDayUTC,
+ // In milliseconds, see JSDate::GetUTCField.
kTimezoneOffset
};
diff --git a/deps/v8/src/objects/js-plural-rules-inl.h b/deps/v8/src/objects/js-plural-rules-inl.h
index f522ae92d30..6d395097d9b 100644
--- a/deps/v8/src/objects/js-plural-rules-inl.h
+++ b/deps/v8/src/objects/js-plural-rules-inl.h
@@ -31,21 +31,21 @@ void JSPluralRules::set_flags(int value) {
flags_.store(this, Smi::FromInt(value));
}
-Tagged<CppGCManaged<icu::PluralRules>> JSPluralRules::icu_plural_rules() const {
- return Cast<CppGCManaged<icu::PluralRules>>(icu_plural_rules_.load());
+Tagged<Managed<icu::PluralRules>> JSPluralRules::icu_plural_rules() const {
+ return Cast<Managed<icu::PluralRules>>(icu_plural_rules_.load());
}
void JSPluralRules::set_icu_plural_rules(
- Tagged<CppGCManaged<icu::PluralRules>> value, WriteBarrierMode mode) {
+ Tagged<Managed<icu::PluralRules>> value, WriteBarrierMode mode) {
icu_plural_rules_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+Tagged<Managed<icu::number::LocalizedNumberFormatter>>
JSPluralRules::icu_number_formatter() const {
- return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
+ return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSPluralRules::set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode) {
icu_number_formatter_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-plural-rules.cc b/deps/v8/src/objects/js-plural-rules.cc
index ff863ddb421..6e7cccf3f20 100644
--- a/deps/v8/src/objects/js-plural-rules.cc
+++ b/deps/v8/src/objects/js-plural-rules.cc
@@ -179,13 +179,12 @@ MaybeDirectHandle<JSPluralRules> JSPluralRules::New(
icu::number::LocalizedNumberFormatter icu_number_formatter =
settings.locale(icu_locale);
- DirectHandle<CppGCManaged<icu::PluralRules>> managed_plural_rules =
- CppGCManaged<icu::PluralRules>::Create(isolate, 0,
- std::move(icu_plural_rules));
+ DirectHandle<Managed<icu::PluralRules>> managed_plural_rules =
+ Managed<icu::PluralRules>::From(isolate, 0, std::move(icu_plural_rules));
- DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<Managed<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
+ Managed<icu::number::LocalizedNumberFormatter>::From(
isolate, 0,
std::make_shared<icu::number::LocalizedNumberFormatter>(
icu_number_formatter));
@@ -211,11 +210,11 @@ MaybeDirectHandle<JSPluralRules> JSPluralRules::New(
MaybeDirectHandle<String> JSPluralRules::ResolvePlural(
Isolate* isolate, DirectHandle<JSPluralRules> plural_rules, double number) {
- CppGCManaged<icu::PluralRules>::Ptr icu_plural_rules =
+ Managed<icu::PluralRules>::Ptr icu_plural_rules =
plural_rules->icu_plural_rules()->ptr();
DCHECK_NOT_NULL(icu_plural_rules);
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr fmt =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr fmt =
plural_rules->icu_number_formatter()->ptr();
DCHECK_NOT_NULL(fmt);
@@ -234,7 +233,7 @@ MaybeDirectHandle<String> JSPluralRules::ResolvePlural(
MaybeDirectHandle<String> JSPluralRules::ResolvePluralRange(
Isolate* isolate, DirectHandle<JSPluralRules> plural_rules, double x,
double y) {
- CppGCManaged<icu::PluralRules>::Ptr icu_plural_rules =
+ Managed<icu::PluralRules>::Ptr icu_plural_rules =
plural_rules->icu_plural_rules()->ptr();
DCHECK_NOT_NULL(icu_plural_rules);
@@ -295,7 +294,7 @@ DirectHandle<JSObject> JSPluralRules::ResolvedOptions(
plural_rules->TypeAsString(isolate), "type");
UErrorCode status = U_ZERO_ERROR;
- CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
+ Managed<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
plural_rules->icu_number_formatter()->ptr();
icu::UnicodeString skeleton = icu_number_formatter->toSkeleton(status);
DCHECK(U_SUCCESS(status));
@@ -337,7 +336,7 @@ DirectHandle<JSObject> JSPluralRules::ResolvedOptions(
// results of PluralRuleSelect for the selected locale pr.[[Locale]], sorted
// according to the following order: "zero", "one", "two", "few", "many",
// "other".
- CppGCManaged<icu::PluralRules>::Ptr icu_plural_rules =
+ Managed<icu::PluralRules>::Ptr icu_plural_rules =
plural_rules->icu_plural_rules()->ptr();
DCHECK_NOT_NULL(icu_plural_rules);
diff --git a/deps/v8/src/objects/js-plural-rules.h b/deps/v8/src/objects/js-plural-rules.h
index 7be9e6517a8..e66c3014b20 100644
--- a/deps/v8/src/objects/js-plural-rules.h
+++ b/deps/v8/src/objects/js-plural-rules.h
@@ -74,15 +74,15 @@ V8_OBJECT class JSPluralRules : public JSObject {
inline int flags() const;
inline void set_flags(int value);
- inline Tagged<CppGCManaged<icu::PluralRules>> icu_plural_rules() const;
+ inline Tagged<Managed<icu::PluralRules>> icu_plural_rules() const;
inline void set_icu_plural_rules(
- Tagged<CppGCManaged<icu::PluralRules>> value,
+ Tagged<Managed<icu::PluralRules>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<Managed<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_VERIFIER(JSPluralRules)
@@ -92,9 +92,8 @@ V8_OBJECT class JSPluralRules : public JSObject {
public:
TaggedMember<String> locale_;
TaggedMember<Smi> flags_;
- TaggedMember<CppGCManaged<icu::PluralRules>> icu_plural_rules_;
- TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
- icu_number_formatter_;
+ TaggedMember<Foreign> icu_plural_rules_;
+ TaggedMember<Foreign> icu_number_formatter_;
} V8_OBJECT_END;
inline constexpr int JSPluralRules::kHeaderSize = sizeof(JSPluralRules);
diff --git a/deps/v8/src/objects/js-plural-rules.tq b/deps/v8/src/objects/js-plural-rules.tq
index 0694715eefb..ed81e501622 100644
--- a/deps/v8/src/objects/js-plural-rules.tq
+++ b/deps/v8/src/objects/js-plural-rules.tq
@@ -14,7 +14,7 @@ bitfield struct JSPluralRulesFlags extends uint31 {
extern class JSPluralRules extends JSObject {
locale: String;
flags: SmiTagged<JSPluralRulesFlags>;
- icu_plural_rules: CppGCManagedBase; // CppGCManaged<icu::PluralRules>
+ icu_plural_rules: Foreign; // Managed<icu::PluralRules>
icu_number_formatter:
- CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
+ Foreign; // Managed<icu::number::LocalizedNumberFormatter>
}
diff --git a/deps/v8/src/objects/js-relative-time-format-inl.h b/deps/v8/src/objects/js-relative-time-format-inl.h
index bd55eef3283..632add2449f 100644
--- a/deps/v8/src/objects/js-relative-time-format-inl.h
+++ b/deps/v8/src/objects/js-relative-time-format-inl.h
@@ -34,13 +34,12 @@ void JSRelativeTimeFormat::set_numberingSystem(Tagged<String> value,
numberingSystem_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>>
+Tagged<Managed<icu::RelativeDateTimeFormatter>>
JSRelativeTimeFormat::icu_formatter() const {
- return Cast<CppGCManaged<icu::RelativeDateTimeFormatter>>(
- icu_formatter_.load());
+ return Cast<Managed<icu::RelativeDateTimeFormatter>>(icu_formatter_.load());
}
void JSRelativeTimeFormat::set_icu_formatter(
- Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>> value,
+ Tagged<Managed<icu::RelativeDateTimeFormatter>> value,
WriteBarrierMode mode) {
icu_formatter_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-relative-time-format.cc b/deps/v8/src/objects/js-relative-time-format.cc
index d964d9c8de6..829be9f262c 100644
--- a/deps/v8/src/objects/js-relative-time-format.cc
+++ b/deps/v8/src/objects/js-relative-time-format.cc
@@ -213,9 +213,9 @@ MaybeDirectHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
isolate->factory()->NewStringFromAsciiChecked(
Intl::GetNumberingSystem(icu_locale).c_str());
- DirectHandle<CppGCManaged<icu::RelativeDateTimeFormatter>>
- managed_formatter = CppGCManaged<icu::RelativeDateTimeFormatter>::Create(
- isolate, 0, std::move(icu_formatter));
+ DirectHandle<Managed<icu::RelativeDateTimeFormatter>> managed_formatter =
+ Managed<icu::RelativeDateTimeFormatter>::From(isolate, 0,
+ std::move(icu_formatter));
DirectHandle<JSRelativeTimeFormat> relative_time_format_holder =
Cast<JSRelativeTimeFormat>(
@@ -251,7 +251,7 @@ DirectHandle<String> StyleAsString(Isolate* isolate, Style style) {
DirectHandle<JSObject> JSRelativeTimeFormat::ResolvedOptions(
Isolate* isolate, DirectHandle<JSRelativeTimeFormat> format_holder) {
Factory* factory = isolate->factory();
- CppGCManaged<icu::RelativeDateTimeFormatter>::Ptr formatter =
+ Managed<icu::RelativeDateTimeFormatter>::Ptr formatter =
format_holder->icu_formatter()->ptr();
DCHECK_NOT_NULL(formatter);
DirectHandle<JSObject> result =
@@ -356,7 +356,7 @@ MaybeDirectHandle<T> FormatCommon(
MessageTemplate::kNotFiniteNumber,
isolate->factory()->NewStringFromAsciiChecked(func_name)));
}
- CppGCManaged<icu::RelativeDateTimeFormatter>::Ptr formatter =
+ Managed<icu::RelativeDateTimeFormatter>::Ptr formatter =
format->icu_formatter()->ptr();
DCHECK_NOT_NULL(formatter);
URelativeDateTimeUnit unit_enum;
diff --git a/deps/v8/src/objects/js-relative-time-format.h b/deps/v8/src/objects/js-relative-time-format.h
index ee2de453139..f7d67d95a44 100644
--- a/deps/v8/src/objects/js-relative-time-format.h
+++ b/deps/v8/src/objects/js-relative-time-format.h
@@ -64,10 +64,9 @@ V8_OBJECT class JSRelativeTimeFormat : public JSObject {
inline void set_numberingSystem(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>>
- icu_formatter() const;
+ inline Tagged<Managed<icu::RelativeDateTimeFormatter>> icu_formatter() const;
inline void set_icu_formatter(
- Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>> value,
+ Tagged<Managed<icu::RelativeDateTimeFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int flags() const;
@@ -101,7 +100,7 @@ V8_OBJECT class JSRelativeTimeFormat : public JSObject {
public:
TaggedMember<String> locale_;
TaggedMember<String> numberingSystem_;
- TaggedMember<CppGCManaged<icu::RelativeDateTimeFormatter>> icu_formatter_;
+ TaggedMember<Foreign> icu_formatter_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-relative-time-format.tq b/deps/v8/src/objects/js-relative-time-format.tq
index e14ae99e2c6..f5f2c990973 100644
--- a/deps/v8/src/objects/js-relative-time-format.tq
+++ b/deps/v8/src/objects/js-relative-time-format.tq
@@ -15,7 +15,6 @@ bitfield struct JSRelativeTimeFormatFlags extends uint31 {
extern class JSRelativeTimeFormat extends JSObject {
locale: String;
numberingSystem: String;
- icu_formatter:
- CppGCManagedBase; // CppGCManaged<icu::RelativeDateTimeFormatter>
+ icu_formatter: Foreign; // Managed<icu::RelativeDateTimeFormatter>
flags: SmiTagged<JSRelativeTimeFormatFlags>;
}
diff --git a/deps/v8/src/objects/js-segmenter-inl.h b/deps/v8/src/objects/js-segmenter-inl.h
index ff27f0874ed..fc2724b0fc3 100644
--- a/deps/v8/src/objects/js-segmenter-inl.h
+++ b/deps/v8/src/objects/js-segmenter-inl.h
@@ -25,11 +25,11 @@ void JSSegmenter::set_locale(Tagged<String> value, WriteBarrierMode mode) {
locale_.store(this, value, mode);
}
-Tagged<CppGCManaged<icu::BreakIterator>> JSSegmenter::icu_break_iterator() const {
- return Cast<CppGCManaged<icu::BreakIterator>>(icu_break_iterator_.load());
+Tagged<Managed<icu::BreakIterator>> JSSegmenter::icu_break_iterator() const {
+ return Cast<Managed<icu::BreakIterator>>(icu_break_iterator_.load());
}
void JSSegmenter::set_icu_break_iterator(
- Tagged<CppGCManaged<icu::BreakIterator>> value, WriteBarrierMode mode) {
+ Tagged<Managed<icu::BreakIterator>> value, WriteBarrierMode mode) {
icu_break_iterator_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-segmenter.cc b/deps/v8/src/objects/js-segmenter.cc
index 3fc43dca822..5186cce701a 100644
--- a/deps/v8/src/objects/js-segmenter.cc
+++ b/deps/v8/src/objects/js-segmenter.cc
@@ -98,9 +98,9 @@ MaybeDirectHandle<JSSegmenter> JSSegmenter::New(
DCHECK(U_SUCCESS(status));
DCHECK_NOT_NULL(icu_break_iterator.get());
- DirectHandle<CppGCManaged<icu::BreakIterator>> managed_break_iterator =
- CppGCManaged<icu::BreakIterator>::Create(isolate, 0,
- std::move(icu_break_iterator));
+ DirectHandle<Managed<icu::BreakIterator>> managed_break_iterator =
+ Managed<icu::BreakIterator>::From(isolate, 0,
+ std::move(icu_break_iterator));
// Now all properties are ready, so we can allocate the result object.
DirectHandle<JSSegmenter> segmenter =
diff --git a/deps/v8/src/objects/js-segmenter.h b/deps/v8/src/objects/js-segmenter.h
index 0b9b7281d61..0689d93bf0e 100644
--- a/deps/v8/src/objects/js-segmenter.h
+++ b/deps/v8/src/objects/js-segmenter.h
@@ -49,9 +49,9 @@ V8_OBJECT class JSSegmenter : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<CppGCManaged<icu::BreakIterator>> icu_break_iterator() const;
+ inline Tagged<Managed<icu::BreakIterator>> icu_break_iterator() const;
inline void set_icu_break_iterator(
- Tagged<CppGCManaged<icu::BreakIterator>> value,
+ Tagged<Managed<icu::BreakIterator>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int flags() const;
@@ -86,7 +86,7 @@ V8_OBJECT class JSSegmenter : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<CppGCManaged<icu::BreakIterator>> icu_break_iterator_;
+ TaggedMember<Foreign> icu_break_iterator_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-segmenter.tq b/deps/v8/src/objects/js-segmenter.tq
index 2dabdf17261..5933038f289 100644
--- a/deps/v8/src/objects/js-segmenter.tq
+++ b/deps/v8/src/objects/js-segmenter.tq
@@ -14,6 +14,6 @@ bitfield struct JSSegmenterFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSSegmenter extends JSObject {
locale: String;
- icu_break_iterator: CppGCManagedBase; // CppGCManaged<icu::BreakIterator>
+ icu_break_iterator: Foreign; // Managed<icu::BreakIterator>
flags: SmiTagged<JSSegmenterFlags>;
}
diff --git a/deps/v8/src/objects/lookup-inl.h b/deps/v8/src/objects/lookup-inl.h
index a14a9b2e36f..c3413668255 100644
--- a/deps/v8/src/objects/lookup-inl.h
+++ b/deps/v8/src/objects/lookup-inl.h
@@ -294,13 +294,24 @@ bool LookupIterator::ExtendingNonExtensible(DirectHandle<JSReceiver> receiver) {
if (IsAlwaysSharedSpaceJSObjectMap(receiver_map)) {
return true;
}
+#if V8_ENABLE_WEBASSEMBLY
+ // Wasm objects have a fixed layout and must never transition their map.
+ if (IsWasmObjectMap(receiver_map)) {
+ return true;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
+
// Extending non-extensible objects with private fields is currently allowed,
// but we're disallowing it soon.
DCHECK(!receiver_map->is_extensible());
DCHECK(name_->IsAnyPrivate());
- if (name_->IsAnyPrivateName()) {
- isolate()->CountUsage(v8::Isolate::kExtendingNonExtensibleWithPrivate);
+ // Internal private symbols are engine implementation details and can always
+ // be added to non-extensible objects.
+ if (name_->IsPrivateInternal()) {
+ return false;
}
+ DCHECK(name_->IsAnyPrivateName());
+ isolate()->CountUsage(v8::Isolate::kExtendingNonExtensibleWithPrivate);
return v8_flags.js_nonextensible_applies_to_private;
}
diff --git a/deps/v8/src/objects/lookup.cc b/deps/v8/src/objects/lookup.cc
index 07834bc499c..872d78cc45b 100644
--- a/deps/v8/src/objects/lookup.cc
+++ b/deps/v8/src/objects/lookup.cc
@@ -672,6 +672,9 @@ void LookupIterator::PrepareTransitionToDataProperty(
DCHECK_IMPLIES(!receiver.is_identical_to(GetStoreTarget<JSReceiver>()),
name_for_transition()->IsAnyPrivateName());
DCHECK(!IsAlwaysSharedSpaceJSObject(*receiver));
+#if V8_ENABLE_WEBASSEMBLY
+ DCHECK(!IsWasmObject(*receiver));
+#endif
if (state_ == TRANSITION) return;
if (!IsElement() && name_for_transition()->IsAnyPrivate()) {
diff --git a/deps/v8/src/objects/managed-inl.h b/deps/v8/src/objects/managed-inl.h
index c72e5f9bce8..c9615e9fab2 100644
--- a/deps/v8/src/objects/managed-inl.h
+++ b/deps/v8/src/objects/managed-inl.h
@@ -35,7 +35,6 @@ template <class CppType>
DirectHandle<Managed<CppType>> Managed<CppType>::From(
Isolate* isolate, size_t estimated_size,
std::shared_ptr<CppType> shared_ptr, AllocationType allocation_type) {
- SharedObjectConditionalSafePublishGuard publish_guard(allocation_type);
static constexpr ExternalPointerTag kTag = TagForManaged<CppType>::value;
static_assert(IsManagedExternalPointerType(kTag));
SharedFlag shared = SharedFlag(IsSharedAllocationType(allocation_type));
@@ -51,6 +50,8 @@ DirectHandle<Managed<CppType>> Managed<CppType>::From(
reinterpret_cast<Address>(destructor), allocation_type));
IndirectHandle<Object> global_handle =
isolate->global_handles()->Create(*handle);
+ SharedObjectConditionalSafePublishGuard publish_guard(*handle,
+ allocation_type);
destructor->global_handle_location_ = global_handle.location();
GlobalHandles::MakeWeak(destructor->global_handle_location_, destructor,
&ManagedObjectFinalizer,
@@ -84,9 +85,9 @@ DirectHandle<TrustedManaged<CppType>> TrustedManaged<CppType>::From(
}
inline CppGCManagedWrapper* CppGCManagedBase::GetWrapper() const {
- return reinterpret_cast<CppGCManagedWrapper*>(ReadCppHeapPointerField(
- offsetof(CppGCManagedBase, cpp_gc_wrapper_), Isolate::Current(),
- CppHeapPointerTag::kCppGCManagedTag));
+ return reinterpret_cast<CppGCManagedWrapper*>(
+ ReadCppHeapPointerField(offsetof(CppGCManagedBase, cpp_gc_wrapper_),
+ Isolate::Current(), kCppGCManagedTag));
}
inline size_t CppGCManagedBase::estimated_size() const {
@@ -110,8 +111,7 @@ Handle<CppGCManaged<CppType>> CppGCManaged<CppType>::Create(
*isolate->factory()->NewCppGCManagedBase(allocation_type);
raw->WriteLazilyInitializedCppHeapPointerField(
offsetof(CppGCManagedBase, cpp_gc_wrapper_), isolate,
- reinterpret_cast<Address>(destructor),
- CppHeapPointerTag::kCppGCManagedTag);
+ reinterpret_cast<Address>(destructor), kCppGCManagedTag);
WriteBarrier::ForCppHeapPointer(
raw,
raw->RawCppHeapPointerField(offsetof(CppGCManagedBase, cpp_gc_wrapper_)),
diff --git a/deps/v8/src/objects/managed-type-id.h b/deps/v8/src/objects/managed-type-id.h
index afcad593df0..766019d1538 100644
--- a/deps/v8/src/objects/managed-type-id.h
+++ b/deps/v8/src/objects/managed-type-id.h
@@ -27,26 +27,8 @@ constexpr const char* ToString(ManagedTypeId type_id) {
return "WasmManagedData";
case ManagedTypeId::kWasmNativeModule:
return "WasmNativeModule";
- case ManagedTypeId::kIcuBreakIterator:
- return "IcuBreakIterator";
case ManagedTypeId::kIcuBreakIteratorWithText:
return "IcuBreakIteratorWithText";
- case ManagedTypeId::kIcuLocale:
- return "IcuLocale";
- case ManagedTypeId::kIcuSimpleDateFormat:
- return "IcuSimpleDateFormat";
- case ManagedTypeId::kIcuDateIntervalFormat:
- return "IcuDateIntervalFormat";
- case ManagedTypeId::kIcuRelativeDateTimeFormatter:
- return "IcuRelativeDateTimeFormatter";
- case ManagedTypeId::kIcuListFormatter:
- return "IcuListFormatter";
- case ManagedTypeId::kIcuCollator:
- return "IcuCollator";
- case ManagedTypeId::kIcuPluralRules:
- return "IcuPluralRules";
- case ManagedTypeId::kIcuLocalizedNumberFormatter:
- return "IcuLocalizedNumberFormatter";
case ManagedTypeId::kTemporalDuration:
return "TemporalDuration";
case ManagedTypeId::kTemporalInstant:
diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc
index dbd60ea0ff9..a6f6a26a945 100644
--- a/deps/v8/src/objects/map.cc
+++ b/deps/v8/src/objects/map.cc
@@ -6,6 +6,7 @@
#include <optional>
+#include "src/base/hashing.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/execution/frames.h"
@@ -1012,6 +1013,8 @@ Handle<Map> Map::GetDerivedMap(Isolate* isolate, DirectHandle<Map> from,
return map;
}
+ if (from->prototype() == *prototype) return handle(*from, isolate);
+
// The TransitionToPrototype map will not have new_target_is_base reset. But
// we don't need it to for proxies.
return Map::TransitionRootMapToPrototypeForNewObject(isolate, from,
@@ -2377,8 +2380,8 @@ Handle<Map> Map::CopyReplaceDescriptor(
}
int Map::Hash(Isolate* isolate, Tagged<HeapObject> prototype) {
- // For performance reasons we only hash the 2 most variable fields of a map:
- // prototype and bit_field2.
+ // Hash the prototype, instance type and bit_field2, mixing their bits before
+ // NormalizedMapCache reduces the hash to a cache index.
int prototype_hash;
if (IsNull(prototype)) {
@@ -2389,7 +2392,10 @@ int Map::Hash(Isolate* isolate, Tagged<HeapObject> prototype) {
prototype_hash = receiver->GetOrCreateIdentityHash(isolate).value();
}
- return prototype_hash ^ bit_field2();
+ size_t hash =
+ base::Hasher::Combine(prototype_hash, static_cast<int>(bit_field2()),
+ static_cast<int>(instance_type()));
+ return static_cast<int>(hash & 0x7FFFFFFF);
}
namespace {
@@ -2696,6 +2702,7 @@ Handle<Map> Map::TransitionRootMapToPrototypeForNewObject(
Isolate* isolate, DirectHandle<Map> map,
DirectHandle<JSPrototype> prototype) {
DCHECK(IsUndefined(map->GetBackPointer()));
+ DCHECK_NE(map->prototype(), *prototype);
Handle<Map> new_map = TransitionToUpdatePrototype(isolate, map, prototype);
if (new_map->GetBackPointer() != *map &&
map->IsInobjectSlackTrackingInProgress()) {
@@ -2711,6 +2718,7 @@ Handle<Map> Map::TransitionToUpdatePrototype(
DirectHandle<JSPrototype> prototype) {
Handle<Map> new_map;
DCHECK(IsUndefined(map->GetBackPointer()));
+ DCHECK_NE(map->prototype(), *prototype);
if (auto maybe_map = TransitionsAccessor::GetPrototypeTransition(
isolate, *map, *prototype)) {
new_map = handle(*maybe_map, isolate);
diff --git a/deps/v8/src/objects/module.cc b/deps/v8/src/objects/module.cc
index 1865ea0a5cb..46c4748a66c 100644
--- a/deps/v8/src/objects/module.cc
+++ b/deps/v8/src/objects/module.cc
@@ -457,7 +457,7 @@ MaybeDirectHandle<Object> JSModuleNamespace::GetExport(
}
DirectHandle<Object> value(Cast<Cell>(*object)->value(), isolate);
- if (IsTheHole(*value)) {
+ if (IsTdzHole(*value)) {
// According to https://tc39.es/ecma262/#sec-InnerModuleLinking
// step 10 and
// https://tc39.es/ecma262/#sec-source-text-module-record-initialize-environment
@@ -511,7 +511,7 @@ Maybe<PropertyAttributes> JSModuleNamespace::GetPropertyAttributes(
if (IsTheHole(*lookup)) return Just(ABSENT);
DirectHandle<Object> value(Cast<Cell>(lookup)->value(), isolate);
- if (IsTheHole(*value)) {
+ if (IsTdzHole(*value)) {
isolate->Throw(*isolate->factory()->NewReferenceError(
MessageTemplate::kNotDefined, name));
return Nothing<PropertyAttributes>();
diff --git a/deps/v8/src/objects/object-list-macros.h b/deps/v8/src/objects/object-list-macros.h
index 33a90aea277..fda3b330e96 100644
--- a/deps/v8/src/objects/object-list-macros.h
+++ b/deps/v8/src/objects/object-list-macros.h
@@ -520,11 +520,20 @@ namespace internal {
V(True, true_value, TrueValue) \
V(False, false_value, FalseValue)
+#ifdef V8_ENABLE_TDZ_HOLE
+#define TDZ_HOLE_LIST(V) V(TdzHole, tdz_hole_value, TdzHoleValue)
+#else
+// TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#define TDZ_HOLE_LIST(V) \
+ V(DisabledTdzHole, disabled_tdz_hole_value, DisabledTdzHoleValue)
+#endif
+
#define HOLE_LIST(V) \
V(TheHole, the_hole_value, TheHoleValue) \
V(PropertyCellHole, property_cell_hole_value, PropertyCellHoleValue) \
V(HashTableHole, hash_table_hole_value, HashTableHoleValue) \
V(PromiseHole, promise_hole_value, PromiseHoleValue) \
+ TDZ_HOLE_LIST(V) \
V(ExceptionHole, exception, Exception) \
V(TerminationException, termination_exception, TerminationException) \
V(UninitializedHole, uninitialized_value, UninitializedValue) \
@@ -548,6 +557,11 @@ HEAP_OBJECT_SPECIALIZED_TYPE_LIST(DEF_FWD_DECLARATION)
VIRTUAL_OBJECT_TYPE_LIST(DEF_FWD_DECLARATION)
#undef DEF_FWD_DECLARATION
+#ifndef V8_ENABLE_TDZ_HOLE
+class TheHole;
+using TdzHole = TheHole;
+#endif
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/object-macros.h b/deps/v8/src/objects/object-macros.h
index 0cd9b6fbadf..9ef97ab0934 100644
--- a/deps/v8/src/objects/object-macros.h
+++ b/deps/v8/src/objects/object-macros.h
@@ -908,14 +908,14 @@
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
-#define EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag)
+#define EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, handle)
#else
-#define EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag) \
- do { \
- DCHECK(TrustedHeapLayout::IsOwnedByAnyHeap(object)); \
- WriteBarrier::ForExternalPointer( \
- object, Tagged(object)->RawExternalPointerField(offset, tag), \
- UPDATE_WRITE_BARRIER); \
+#define EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, handle) \
+ do { \
+ DCHECK(TrustedHeapLayout::IsOwnedByAnyHeap(object)); \
+ WriteBarrier::ForExternalPointer( \
+ object, Tagged(object)->RawExternalPointerField(offset, tag), handle, \
+ UPDATE_WRITE_BARRIER); \
} while (false)
#endif
@@ -958,13 +958,16 @@
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
-#define CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, mode)
+#define CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, \
+ handle, mode)
#else
-#define CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, mode) \
+#define CONDITIONAL_EXTERNAL_POINTER_WRITE_BARRIER(object, offset, tag, \
+ handle, mode) \
do { \
DCHECK(TrustedHeapLayout::IsOwnedByAnyHeap(object)); \
WriteBarrier::ForExternalPointer( \
- object, Tagged(object)->RawExternalPointerField(offset, tag), mode); \
+ object, Tagged(object)->RawExternalPointerField(offset, tag), handle, \
+ mode); \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
diff --git a/deps/v8/src/objects/objects-body-descriptors-inl.h b/deps/v8/src/objects/objects-body-descriptors-inl.h
index cf024e02121..eeaa90ad321 100644
--- a/deps/v8/src/objects/objects-body-descriptors-inl.h
+++ b/deps/v8/src/objects/objects-body-descriptors-inl.h
@@ -1416,8 +1416,6 @@ class WasmImportData::BodyDescriptor final : public BodyDescriptorBase {
int object_size, ObjectVisitor* v) {
IterateProtectedPointer(
obj, offsetof(WasmImportData, protected_importing_instance_data_), v);
- IterateProtectedPointer(
- obj, offsetof(WasmImportData, protected_call_origin_), v);
IteratePointer(obj, offsetof(WasmImportData, native_context_), v);
IteratePointer(obj, offsetof(WasmImportData, callable_), v);
IteratePointer(obj, offsetof(WasmImportData, wrapper_budget_), v);
@@ -1452,11 +1450,8 @@ class WasmFunctionData::BodyDescriptor final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
int object_size, ObjectVisitor* v) {
- Tagged<WasmFunctionData> data = UncheckedCast<WasmFunctionData>(obj);
IterateSelfIndirectPointer(obj, kWasmFunctionDataIndirectPointerTagRange,
v);
- IterateCodePointer(obj, &data->wrapper_code_, v,
- IndirectPointerMode::kStrong);
IteratePointer(obj, offsetof(WasmFunctionData, func_ref_), v);
IteratePointer(obj, offsetof(WasmFunctionData, js_promise_flags_), v);
IterateProtectedPointer(obj,
diff --git a/deps/v8/src/objects/objects.h b/deps/v8/src/objects/objects.h
index 53945dacdb4..91258503a2c 100644
--- a/deps/v8/src/objects/objects.h
+++ b/deps/v8/src/objects/objects.h
@@ -15,6 +15,7 @@
#include "src/base/flags.h"
#include "src/base/logging.h"
#include "src/base/memory.h"
+#include "src/base/sanitizer/tsan.h"
#include "src/codegen/constants-arch.h"
#include "src/common/assert-scope.h"
#include "src/common/checks.h"
@@ -796,20 +797,27 @@ class V8_NODISCARD SharedObjectSafePublishGuard final {
};
// Like `SharedObjectsSafePublishGuard`, but only applies the fence
-// if `apply_fence_` is shared.
+// if `apply_fence_` is shared. Also, applies TSAN_RELEASE after the release
+// fence to disable TSAN false positives.
class V8_NODISCARD SharedObjectConditionalSafePublishGuard final {
public:
- explicit SharedObjectConditionalSafePublishGuard(SharedFlag apply_fence)
- : apply_fence_(apply_fence) {}
- explicit SharedObjectConditionalSafePublishGuard(AllocationType allocation)
- : apply_fence_(IsSharedAllocationType(allocation)) {}
+ explicit SharedObjectConditionalSafePublishGuard(Tagged<HeapObject> object,
+ SharedFlag apply_fence)
+ : object_(object), apply_fence_(apply_fence) {}
+ explicit SharedObjectConditionalSafePublishGuard(Tagged<HeapObject> object,
+ AllocationType allocation)
+ : object_(object), apply_fence_(IsSharedAllocationType(allocation)) {}
~SharedObjectConditionalSafePublishGuard() {
if (apply_fence_) {
std::atomic_thread_fence(std::memory_order_release);
+ TSAN_RELEASE(object_.address());
}
}
private:
+ // Required due to the raw Tagged<HeapObject> below.
+ DisallowGarbageCollection no_gc;
+ Tagged<HeapObject> object_;
SharedFlag apply_fence_;
};
diff --git a/deps/v8/src/objects/oddball-predicates-inl.h b/deps/v8/src/objects/oddball-predicates-inl.h
index ec170f7fd2a..d0394f669d2 100644
--- a/deps/v8/src/objects/oddball-predicates-inl.h
+++ b/deps/v8/src/objects/oddball-predicates-inl.h
@@ -25,6 +25,9 @@ namespace v8::internal {
}
ODDBALL_LIST(IS_TYPE_FUNCTION_DEF)
HOLE_LIST(IS_TYPE_FUNCTION_DEF)
+#ifndef V8_ENABLE_TDZ_HOLE
+IS_TYPE_FUNCTION_DEF(TdzHole)
+#endif
IS_TYPE_FUNCTION_DEF(UndefinedContextCell)
#undef IS_TYPE_FUNCTION_DEF
@@ -52,6 +55,9 @@ IS_TYPE_FUNCTION_DEF(UndefinedContextCell)
#endif
ODDBALL_LIST(IS_TYPE_FUNCTION_DEF)
HOLE_LIST(IS_TYPE_FUNCTION_DEF)
+#ifndef V8_ENABLE_TDZ_HOLE
+IS_TYPE_FUNCTION_DEF(TdzHole, the_hole_value, TheHoleValue)
+#endif
IS_TYPE_FUNCTION_DEF(UndefinedContextCell, undefined_context_cell,
UndefinedContextCell)
#undef IS_TYPE_FUNCTION_DEF
diff --git a/deps/v8/src/objects/oddball-predicates.h b/deps/v8/src/objects/oddball-predicates.h
index 5c46630041a..ea7d7ecaaa7 100644
--- a/deps/v8/src/objects/oddball-predicates.h
+++ b/deps/v8/src/objects/oddball-predicates.h
@@ -20,6 +20,9 @@ class Object;
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
HOLE_LIST(IS_TYPE_FUNCTION_DECL)
+#ifndef V8_ENABLE_TDZ_HOLE
+IS_TYPE_FUNCTION_DECL(TdzHole)
+#endif
IS_TYPE_FUNCTION_DECL(UndefinedContextCell)
IS_TYPE_FUNCTION_DECL(NullOrUndefined)
#undef IS_TYPE_FUNCTION_DECL
diff --git a/deps/v8/src/objects/scope-info.cc b/deps/v8/src/objects/scope-info.cc
index 7462ad88643..4986c640a57 100644
--- a/deps/v8/src/objects/scope-info.cc
+++ b/deps/v8/src/objects/scope-info.cc
@@ -112,8 +112,7 @@ bool ScopeInfo::Equals(Tagged<ScopeInfo> other,
// static
template <typename IsolateT>
Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
- MaybeDirectHandle<ScopeInfo> outer_scope,
- FunctionKind closure_function_kind) {
+ MaybeDirectHandle<ScopeInfo> outer_scope) {
// Collect variables.
int context_local_count = 0;
int module_vars_count = 0;
@@ -215,8 +214,10 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
scope->AsModuleScope()->module());
}
+ FunctionKind function_kind = FunctionKind::kNormalFunction;
bool sloppy_eval_can_extend_vars = false;
if (scope->is_declaration_scope()) {
+ function_kind = scope->AsDeclarationScope()->function_kind();
sloppy_eval_can_extend_vars =
scope->AsDeclarationScope()->sloppy_eval_can_extend_vars();
}
@@ -282,7 +283,7 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
FunctionVariableBits::encode(function_name_info) |
HasInferredFunctionNameBit::encode(has_inferred_function_name) |
HasSimpleParametersBit::encode(has_simple_parameters) |
- FunctionKindBits::encode(closure_function_kind) |
+ FunctionKindBits::encode(function_kind) |
HasOuterScopeInfoBit::encode(has_outer_scope_info) |
IsDebugEvaluateScopeBit::encode(false) |
ForceContextAllocationBit::encode(
@@ -516,13 +517,11 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Handle<ScopeInfo> ScopeInfo::Create(
Isolate* isolate, Zone* zone, Scope* scope,
- MaybeDirectHandle<ScopeInfo> outer_scope,
- FunctionKind closure_function_kind);
+ MaybeDirectHandle<ScopeInfo> outer_scope);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Handle<ScopeInfo> ScopeInfo::Create(
LocalIsolate* isolate, Zone* zone, Scope* scope,
- MaybeDirectHandle<ScopeInfo> outer_scope,
- FunctionKind closure_function_kind);
+ MaybeDirectHandle<ScopeInfo> outer_scope);
// static
DirectHandle<ScopeInfo> ScopeInfo::CreateForWithScope(
@@ -771,8 +770,7 @@ ScopeType ScopeInfo::scope_type() const {
}
bool ScopeInfo::is_script_scope() const {
- return !this->IsEmpty() &&
- (scope_type() == SCRIPT_SCOPE || scope_type() == REPL_MODE_SCOPE);
+ return scope_type() == SCRIPT_SCOPE || scope_type() == REPL_MODE_SCOPE;
}
bool ScopeInfo::SloppyEvalCanExtendVars() const {
@@ -792,7 +790,6 @@ bool ScopeInfo::is_declaration_scope() const {
}
int ScopeInfo::ContextLength() const {
- if (this->IsEmpty()) return 0;
int context_locals = ContextLocalCount();
bool function_name_context_slot = HasContextAllocatedFunctionName();
bool force_context = ForceContextAllocationBit::decode(Flags());
@@ -879,10 +876,9 @@ bool ScopeInfo::IsSloppyNormalJSFunction() const {
}
bool ScopeInfo::CanOnlyAccessFixedFormalParameters() const {
+ DCHECK(!IsEmpty());
FunctionKind function_kind = this->function_kind();
return
- // Filter out builtins.
- !IsEmpty() &&
// Can't be a SloppyNormalJSFunction.
!IsSloppyNormalJSFunction() &&
// TODO(dcarney): Make this function kind filter exact. It's currently
@@ -910,8 +906,6 @@ bool ScopeInfo::HasInferredFunctionName() const {
return HasInferredFunctionNameBit::decode(Flags());
}
-bool ScopeInfo::HasPositionInfo() const { return !this->IsEmpty(); }
-
bool ScopeInfo::HasSharedFunctionName() const {
return FunctionName() != SharedFunctionInfo::kNoSharedNameSentinel;
}
@@ -982,17 +976,17 @@ Tagged<String> ScopeInfo::FunctionDebugName() const {
}
int ScopeInfo::StartPosition() const {
- DCHECK(HasPositionInfo());
+ DCHECK(!this->IsEmpty());
return position_info_start();
}
int ScopeInfo::EndPosition() const {
- DCHECK(HasPositionInfo());
+ DCHECK(!this->IsEmpty());
return position_info_end();
}
void ScopeInfo::SetPositionInfo(int start, int end) {
- DCHECK(HasPositionInfo());
+ DCHECK(!this->IsEmpty());
DCHECK_LE(start, end);
set_position_info_start(start);
set_position_info_end(end);
@@ -1123,8 +1117,7 @@ int ScopeInfo::ContextSlotIndex(Tagged<String> name,
DisallowGarbageCollection no_gc;
DCHECK(IsInternalizedString(name));
DCHECK_NOT_NULL(lookup_result);
-
- if (this->IsEmpty()) return -1;
+ DCHECK_IMPLIES(this->IsEmpty(), ContextLocalCount() == 0);
int index = HasInlinedLocalNames()
? InlinedLocalNamesLookup(name)
@@ -1298,13 +1291,9 @@ uint32_t ScopeInfo::Hash() {
// Hash ScopeInfo based on its start and end position.
// Note: Ideally we'd also have the script ID. But since we only use the
// hash in a debug-evaluate cache, we don't worry too much about collisions.
- if (HasPositionInfo()) {
- return static_cast<uint32_t>(base::hash_combine(
- flags(kRelaxedLoad), StartPosition(), EndPosition()));
- }
-
+ DCHECK(!this->IsEmpty());
return static_cast<uint32_t>(
- base::hash_combine(flags(kRelaxedLoad), context_local_count()));
+ base::hash_combine(flags(kRelaxedLoad), StartPosition(), EndPosition()));
}
std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var_info) {
diff --git a/deps/v8/src/objects/scope-info.h b/deps/v8/src/objects/scope-info.h
index 5a8754a06b7..e4e51743906 100644
--- a/deps/v8/src/objects/scope-info.h
+++ b/deps/v8/src/objects/scope-info.h
@@ -122,7 +122,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
// Parameters allocated in the context count as context allocated locals. If
// no contexts are allocated for this scope ContextLength returns 0.
int ContextLength() const;
- int ContextHeaderLength() const;
+ V8_EXPORT_PRIVATE int ContextHeaderLength() const;
// Returns true if the respective contexts have a context extension slot.
V8_EXPORT_PRIVATE bool HasContextExtensionSlot() const;
@@ -169,9 +169,6 @@ V8_OBJECT class ScopeInfo : public HeapObject {
V8_EXPORT_PRIVATE void SetFunctionName(Tagged<UnionOf<Smi, String>> name);
V8_EXPORT_PRIVATE void SetInferredFunctionName(Tagged<String> name);
- // Does this scope belong to a function?
- bool HasPositionInfo() const;
-
bool IsWrappedFunctionScope() const;
// Return if contexts are allocated for this scope.
@@ -199,7 +196,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
int EndPosition() const;
void SetPositionInfo(int start, int end);
- int UniqueIdInScript() const;
+ V8_EXPORT_PRIVATE int UniqueIdInScript() const;
Tagged<SourceTextModuleInfo> ModuleDescriptorInfo() const;
@@ -217,7 +214,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
// Return the name of a given context local.
// It should only be used if inlined local names.
- Tagged<String> ContextInlinedLocalName(int var) const;
+ V8_EXPORT_PRIVATE Tagged<String> ContextInlinedLocalName(int var) const;
// Return the mode of the given context local.
VariableMode ContextLocalMode(int var) const;
@@ -292,7 +289,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
void SetIsDebugEvaluateScope();
// Return the outer ScopeInfo if present.
- Tagged<ScopeInfo> OuterScopeInfo() const;
+ V8_EXPORT_PRIVATE Tagged<ScopeInfo> OuterScopeInfo() const;
bool is_script_scope() const;
@@ -309,8 +306,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
template <typename IsolateT>
static Handle<ScopeInfo> Create(IsolateT* isolate, Zone* zone, Scope* scope,
- MaybeDirectHandle<ScopeInfo> outer_scope,
- FunctionKind closure_function_kind);
+ MaybeDirectHandle<ScopeInfo> outer_scope);
V8_EXPORT_PRIVATE static DirectHandle<ScopeInfo> CreateForWithScope(
Isolate* isolate, MaybeDirectHandle<ScopeInfo> outer_scope);
V8_EXPORT_PRIVATE static DirectHandle<ScopeInfo> CreateForEmptyFunction(
diff --git a/deps/v8/src/objects/script-inl.h b/deps/v8/src/objects/script-inl.h
index bc3d052a06e..9b241848d93 100644
--- a/deps/v8/src/objects/script-inl.h
+++ b/deps/v8/src/objects/script-inl.h
@@ -10,9 +10,10 @@
#include "src/objects/heap-object-inl.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/scope-info.h"
#include "src/objects/smi-inl.h"
-#include "src/objects/string-inl.h"
-#include "src/objects/struct-inl.h"
+#include "src/objects/tagged-field-inl.h"
+#include "src/roots/roots-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -92,13 +93,6 @@ Tagged<Object> Script::wasm_managed_native_module() const {
DCHECK_EQ(type(), Type::kWasm);
return eval_from_position_.load();
}
-void Script::set_wasm_managed_native_module(Tagged<Object> value,
- WriteBarrierMode mode) {
- DCHECK_EQ(type(), Type::kWasm);
- eval_from_position_.store(this, Cast<UnionOf<Smi, CppGCManagedBase>>(value),
- mode);
-}
-
Tagged<WeakArrayList> Script::wasm_weak_instance_list() const {
DCHECK_EQ(type(), Type::kWasm);
return Cast<WeakArrayList>(infos_.load());
@@ -169,12 +163,6 @@ void Script::set_eval_from_position(int value) {
Tagged<Object> Script::eval_from_scope_info() const {
return eval_from_scope_info_.load();
}
-void Script::set_eval_from_scope_info(Tagged<Object> value,
- WriteBarrierMode mode) {
- eval_from_scope_info_.store(this, Cast<UnionOf<ScopeInfo, Undefined>>(value),
- mode);
-}
-
bool Script::has_eval_from_scope_info() const {
return IsScopeInfo(eval_from_scope_info());
}
@@ -196,15 +184,6 @@ void Script::set_infos(Tagged<WeakFixedArray> value, WriteBarrierMode mode) {
}
#if V8_ENABLE_WEBASSEMBLY
-bool Script::has_wasm_breakpoint_infos() const {
- return type() == Type::kWasm &&
- wasm_breakpoint_infos()->ulength().value() > 0;
-}
-
-CppGCManaged<wasm::NativeModule>::Ptr Script::wasm_native_module() const {
- return Cast<CppGCManaged<wasm::NativeModule>>(wasm_managed_native_module())
- ->ptr();
-}
bool Script::break_on_entry() const { return BreakOnEntryBit::decode(flags()); }
@@ -326,19 +305,6 @@ void Script::set_source_hash(Tagged<UnionOf<String, Undefined>> value,
source_hash_.store(this, value, mode);
}
-bool Script::HasValidSource() {
- Tagged<Object> src = this->source();
- if (!IsString(src)) return true;
- Tagged<String> src_str = Cast<String>(src);
- if (!StringShape(src_str).IsExternal()) return true;
- if (src_str->IsOneByteRepresentation()) {
- return Cast<ExternalOneByteString>(src)->resource() != nullptr;
- } else if (src_str->IsTwoByteRepresentation()) {
- return Cast<ExternalTwoByteString>(src)->resource() != nullptr;
- }
- return true;
-}
-
bool Script::has_line_ends() const { return line_ends() != Smi::zero(); }
bool Script::CanHaveLineEnds() const {
@@ -360,21 +326,6 @@ void Script::InitLineEnds(LocalIsolate* isolate, DirectHandle<Script> script) {
Script::InitLineEndsInternal(isolate, script);
}
-bool Script::HasSourceURLComment() const {
- return IsString(source_url()) && Cast<String>(source_url())->length() != 0;
-}
-
-bool Script::HasSourceMappingURLComment() const {
- return IsString(source_mapping_url()) &&
- Cast<String>(source_mapping_url())->length() != 0;
-}
-
-bool Script::IsMaybeUnfinalized(Isolate* isolate) const {
- // TODO(v8:12051): A more robust detection, e.g. with a dedicated sentinel
- // value.
- return IsUndefined(source()) || Cast<String>(source())->length() == 0;
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/script.cc b/deps/v8/src/objects/script.cc
index f7378a63183..1a24f18583d 100644
--- a/deps/v8/src/objects/script.cc
+++ b/deps/v8/src/objects/script.cc
@@ -6,13 +6,70 @@
#include "src/ast/ast.h"
#include "src/common/globals.h"
+#include "src/objects/fixed-array-inl.h"
+#include "src/objects/objects-inl.h"
+#include "src/objects/script-inl.h"
#include "src/objects/shared-function-info-inl.h"
+#include "src/objects/string-inl.h"
#include "src/tracing/traced-value.h"
#include "src/utils/hex-format.h"
#include "src/utils/sha-256.h"
namespace v8::internal {
+#if V8_ENABLE_WEBASSEMBLY
+void Script::set_wasm_managed_native_module(Tagged<Object> value,
+ WriteBarrierMode mode) {
+ DCHECK_EQ(type(), Type::kWasm);
+ eval_from_position_.store(this, Cast<UnionOf<Smi, CppGCManagedBase>>(value),
+ mode);
+}
+
+CppGCManaged<wasm::NativeModule>::Ptr Script::wasm_native_module() const {
+ return Cast<CppGCManaged<wasm::NativeModule>>(wasm_managed_native_module())
+ ->ptr();
+}
+
+bool Script::has_wasm_breakpoint_infos() const {
+ return type() == Type::kWasm &&
+ wasm_breakpoint_infos()->ulength().value() > 0;
+}
+#endif // V8_ENABLE_WEBASSEMBLY
+
+void Script::set_eval_from_scope_info(Tagged<Object> value,
+ WriteBarrierMode mode) {
+ eval_from_scope_info_.store(this, Cast<UnionOf<ScopeInfo, Undefined>>(value),
+ mode);
+}
+
+bool Script::HasValidSource() {
+ Tagged<Object> src = this->source();
+ if (!IsString(src)) return true;
+ Tagged<String> src_str = Cast<String>(src);
+ if (!StringShape(src_str).IsExternal()) return true;
+ if (src_str->IsOneByteRepresentation()) {
+ return Cast<ExternalOneByteString>(src)->resource() != nullptr;
+ } else if (src_str->IsTwoByteRepresentation()) {
+ return Cast<ExternalTwoByteString>(src)->resource() != nullptr;
+ }
+ return true;
+}
+
+bool Script::HasSourceURLComment() const {
+ return IsString(source_url()) && Cast<String>(source_url())->length() != 0;
+}
+
+bool Script::HasSourceMappingURLComment() const {
+ return IsString(source_mapping_url()) &&
+ Cast<String>(source_mapping_url())->length() != 0;
+}
+
+bool Script::IsMaybeUnfinalized(Isolate* isolate) const {
+ // TODO(v8:12051): A more robust detection, e.g. with a dedicated sentinel
+ // value.
+ return IsUndefined(source()) || Cast<String>(source())->length() == 0;
+}
+
const char* ToString(Script::Type type) {
switch (type) {
case Script::Type::kNative:
@@ -83,6 +140,8 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
CHECK_EQ(result->EndPosition(), function_literal->end_position());
CHECK_EQ(result->function_literal_id(kRelaxedLoad),
function_literal->function_literal_id());
+ CHECK_EQ(result->syntax_kind(), function_literal->syntax_kind());
+ CHECK_EQ(result->kind(), function_literal->kind());
function_literal->set_shared_function_info(result);
return result;
}
diff --git a/deps/v8/src/objects/script.h b/deps/v8/src/objects/script.h
index a00960ed486..453a593ff42 100644
--- a/deps/v8/src/objects/script.h
+++ b/deps/v8/src/objects/script.h
@@ -148,8 +148,8 @@ V8_OBJECT class Script : public Struct {
inline void set_eval_from_position(int value);
inline Tagged<Object> eval_from_scope_info() const;
- inline void set_eval_from_scope_info(
- Tagged<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ void set_eval_from_scope_info(Tagged<Object> value,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline bool has_eval_from_scope_info() const;
@@ -167,15 +167,16 @@ V8_OBJECT class Script : public Struct {
inline void set_wasm_breakpoint_infos(
Tagged<FixedArray> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline bool has_wasm_breakpoint_infos() const;
+ bool has_wasm_breakpoint_infos() const;
// [wasm_native_module]: the wasm {NativeModule} this script belongs to.
// This must only be called if the type of this script is TYPE_WASM.
inline Tagged<Object> wasm_managed_native_module() const;
- inline void set_wasm_managed_native_module(
+ void set_wasm_managed_native_module(
Tagged<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline CppGCManaged<wasm::NativeModule>::Ptr wasm_native_module() const;
+ V8_EXPORT_PRIVATE CppGCManaged<wasm::NativeModule>::Ptr wasm_native_module()
+ const;
// [wasm_weak_instance_list]: the list of all {WasmInstanceObject} being
// affected by breakpoints that are managed via this script.
@@ -255,18 +256,18 @@ V8_OBJECT class Script : public Struct {
// If script source is an external string, check that the underlying
// resource is accessible. Otherwise, always return true.
- inline bool HasValidSource();
+ bool HasValidSource();
// If the script has a non-empty sourceURL comment.
- inline bool HasSourceURLComment() const;
+ bool HasSourceURLComment() const;
// If the script has a non-empty sourceMappingURL comment.
- inline bool HasSourceMappingURLComment() const;
+ bool HasSourceMappingURLComment() const;
// Streaming compilation only attaches the source to the Script upon
// finalization. This predicate returns true, if this script may still be
// unfinalized.
- inline bool IsMaybeUnfinalized(Isolate* isolate) const;
+ bool IsMaybeUnfinalized(Isolate* isolate) const;
Tagged<Object> GetNameOrSourceURL();
static DirectHandle<String> GetScriptHash(Isolate* isolate,
diff --git a/deps/v8/src/objects/shared-function-info-inl.h b/deps/v8/src/objects/shared-function-info-inl.h
index b3a8d4c7f3b..93de8a242af 100644
--- a/deps/v8/src/objects/shared-function-info-inl.h
+++ b/deps/v8/src/objects/shared-function-info-inl.h
@@ -20,7 +20,7 @@
#include "src/handles/handles-inl.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/abstract-code.h"
-#include "src/objects/contexts-inl.h"
+#include "src/objects/contexts.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/feedback-vector-inl.h"
#include "src/objects/function-kind.h"
@@ -303,7 +303,11 @@ uint32_t SharedFunctionInfo::unused_parameter_bits() const {
}
bool SharedFunctionInfo::CanOnlyAccessFixedFormalParameters() const {
- return scope_info(kAcquireLoad)->CanOnlyAccessFixedFormalParameters();
+ if (Tagged<ScopeInfo> info;
+ TryCast(name_or_scope_info(kAcquireLoad), &info)) {
+ return info->CanOnlyAccessFixedFormalParameters();
+ }
+ return false;
}
uint16_t SharedFunctionInfo::internal_formal_parameter_count_without_receiver()
@@ -382,12 +386,16 @@ void SharedFunctionInfo::SetName(Tagged<String> name) {
}
bool SharedFunctionInfo::is_script() const {
- return scope_info(kAcquireLoad)->is_script_scope() &&
- Cast<Script>(script())->is_host();
+ if (!is_toplevel()) return false;
+ bool result = scope_info(kAcquireLoad)->is_script_scope();
+ DCHECK_IMPLIES(result, Cast<Script>(script())->is_host());
+ return result;
}
bool SharedFunctionInfo::needs_script_context() const {
- return is_script() && scope_info(kAcquireLoad)->ContextLocalCount() > 0;
+ if (!is_toplevel()) return false;
+ Tagged<ScopeInfo> info = scope_info(kAcquireLoad);
+ return info->is_script_scope() && info->ContextLocalCount() > 0;
}
Tagged<AbstractCode> SharedFunctionInfo::abstract_code(Isolate* isolate) {
@@ -643,6 +651,14 @@ void SharedFunctionInfo::DontAdaptArguments() {
set_formal_parameter_count(kDontAdaptArgumentsSentinel);
}
+bool SharedFunctionInfo::HasScopeInfo() const {
+ return HasScopeInfo(kAcquireLoad);
+}
+
+bool SharedFunctionInfo::HasScopeInfo(AcquireLoadTag tag) const {
+ return IsScopeInfo(name_or_scope_info(tag));
+}
+
DEF_ACQUIRE_GETTER(SharedFunctionInfo, scope_info, Tagged<ScopeInfo>) {
Tagged<Object> maybe_scope_info = name_or_scope_info(tag);
if (IsScopeInfo(maybe_scope_info)) {
@@ -705,25 +721,26 @@ DEF_GETTER(SharedFunctionInfo, outer_scope_info,
}
bool SharedFunctionInfo::HasOuterScopeInfo() const {
- Tagged<ScopeInfo> outer_info;
- Tagged<ScopeInfo> info = scope_info(kAcquireLoad);
- if (info->IsEmpty()) {
- if (is_compiled()) return false;
- Tagged<UnionOf<ScopeInfo, TheHole>> maybe_outer_info = outer_scope_info();
- if (IsTheHole(maybe_outer_info)) return false;
- outer_info = Cast<ScopeInfo>(maybe_outer_info);
- } else {
- if (!info->HasOuterScopeInfo()) return false;
- outer_info = info->OuterScopeInfo();
+ if (Tagged<ScopeInfo> info;
+ TryCast(name_or_scope_info(kAcquireLoad), &info)) {
+ DCHECK_IMPLIES(info->HasOuterScopeInfo(),
+ !info->OuterScopeInfo()->IsEmpty());
+ return info->HasOuterScopeInfo();
}
- return !outer_info->IsEmpty();
+ if (is_compiled()) return false;
+ Tagged<UnionOf<ScopeInfo, TheHole>> maybe_outer_info = outer_scope_info();
+ if (IsTheHole(maybe_outer_info)) return false;
+ DCHECK(!Cast<ScopeInfo>(maybe_outer_info)->IsEmpty());
+ return true;
}
Tagged<ScopeInfo> SharedFunctionInfo::GetOuterScopeInfo() const {
DCHECK(HasOuterScopeInfo());
- Tagged<ScopeInfo> info = scope_info(kAcquireLoad);
- if (info->IsEmpty()) return Cast<ScopeInfo>(outer_scope_info());
- return info->OuterScopeInfo();
+ if (Tagged<ScopeInfo> info;
+ TryCast(name_or_scope_info(kAcquireLoad), &info)) {
+ return info->OuterScopeInfo();
+ }
+ return Cast<ScopeInfo>(outer_scope_info());
}
Tagged<ScopeInfo> SharedFunctionInfo::TryGetScopeInfoForMerge() const {
@@ -761,7 +778,7 @@ void SharedFunctionInfo::set_outer_scope_info(
DCHECK(!is_compiled());
DCHECK(IsTheHole(raw_outer_scope_info_or_feedback_metadata()));
DCHECK(IsTheHole(value) || IsScopeInfo(value));
- DCHECK(scope_info()->IsEmpty());
+ DCHECK(!HasScopeInfo());
set_raw_outer_scope_info_or_feedback_metadata(value, mode);
}
diff --git a/deps/v8/src/objects/shared-function-info.cc b/deps/v8/src/objects/shared-function-info.cc
index 1d731687dc6..5151351c3ac 100644
--- a/deps/v8/src/objects/shared-function-info.cc
+++ b/deps/v8/src/objects/shared-function-info.cc
@@ -115,14 +115,10 @@ Tagged<Code> SharedFunctionInfo::GetCode(Isolate* isolate) const {
return isolate->builtins()->code(Builtin::kCompileLazy);
}
#if V8_ENABLE_WEBASSEMBLY
- if (IsWasmExportedFunctionData(trusted_data)) {
- // Having a WasmExportedFunctionData means the code is in there.
- DCHECK(HasWasmExportedFunctionData(isolate));
- return wasm_exported_function_data()->wrapper_code(isolate);
- }
- if (IsWasmCapiFunctionData(trusted_data)) {
- return wasm_capi_function_data()->wrapper_code(isolate);
- }
+ // Wasm functions (WasmExportedFunction and WasmCapiFunction) install their
+ // wrapper code directly into the JSDispatchTable at creation time (and on
+ // tier-up), rather than storing it on the SharedFunctionInfo.
+ CHECK(!IsWasmFunctionData(trusted_data));
#endif // V8_ENABLE_WEBASSEMBLY
} else {
DCHECK(HasUntrustedData());
@@ -608,7 +604,7 @@ void SharedFunctionInfo::InitFromFunctionLiteral(IsolateT* isolate,
raw_sfi->set_is_toplevel(is_toplevel);
DCHECK(IsTheHole(raw_sfi->outer_scope_info()));
Scope* outer_scope = lit->scope()->GetOuterScopeWithContext();
- if (outer_scope && (!is_toplevel || !outer_scope->is_script_scope())) {
+ if (outer_scope) {
raw_sfi->set_outer_scope_info(*outer_scope->scope_info());
raw_sfi->set_private_name_lookup_skips_outer_class(
lit->scope()->private_name_lookup_skips_outer_class());
@@ -743,12 +739,9 @@ void SharedFunctionInfo::SetFunctionTokenPosition(int function_token_position,
}
int SharedFunctionInfo::StartPosition() const {
- Tagged<Object> maybe_scope_info = name_or_scope_info(kAcquireLoad);
- if (IsScopeInfo(maybe_scope_info)) {
- Tagged<ScopeInfo> info = Cast<ScopeInfo>(maybe_scope_info);
- if (info->HasPositionInfo()) {
- return info->StartPosition();
- }
+ if (Tagged<ScopeInfo> info;
+ TryCast(name_or_scope_info(kAcquireLoad), &info)) {
+ return info->StartPosition();
}
IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
if (HasUncompiledData(isolate)) {
@@ -782,12 +775,9 @@ int SharedFunctionInfo::StartPosition() const {
}
int SharedFunctionInfo::EndPosition() const {
- Tagged<Object> maybe_scope_info = name_or_scope_info(kAcquireLoad);
- if (IsScopeInfo(maybe_scope_info)) {
- Tagged<ScopeInfo> info = Cast<ScopeInfo>(maybe_scope_info);
- if (info->HasPositionInfo()) {
- return info->EndPosition();
- }
+ if (Tagged<ScopeInfo> info;
+ TryCast(name_or_scope_info(kAcquireLoad), &info)) {
+ return info->EndPosition();
}
IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
if (HasUncompiledData(isolate)) {
@@ -892,12 +882,7 @@ void SharedFunctionInfo::UninstallDebugBytecode(
// static
void SharedFunctionInfo::EnsureOldForTesting(Tagged<SharedFunctionInfo> sfi) {
- if (v8_flags.flush_code_based_on_time ||
- v8_flags.flush_code_based_on_tab_visibility) {
- sfi->set_age(kMaxAge);
- } else {
- sfi->set_age(v8_flags.bytecode_old_age);
- }
+ sfi->set_age(kMaxAge);
}
#ifdef DEBUG
diff --git a/deps/v8/src/objects/shared-function-info.h b/deps/v8/src/objects/shared-function-info.h
index a4b91056a48..d5f8a8fc2a9 100644
--- a/deps/v8/src/objects/shared-function-info.h
+++ b/deps/v8/src/objects/shared-function-info.h
@@ -379,6 +379,8 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
static constexpr int kAgeSize = sizeof(uint16_t);
static constexpr uint16_t kMaxAge = UINT16_MAX;
+ inline bool HasScopeInfo() const;
+ inline bool HasScopeInfo(AcquireLoadTag tag) const;
DECL_ACQUIRE_GETTER(scope_info, Tagged<ScopeInfo>)
// Deprecated, use the ACQUIRE version instead.
DECL_GETTER(scope_info, Tagged<ScopeInfo>)
@@ -518,7 +520,7 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
public:
static constexpr IndirectPointerTagRange kTrustedDataIndirectPointerRange =
- kAllIndirectPointerTags;
+ kSFITrustedDataIndirectPointerRange;
inline bool IsApiFunction() const;
inline bool is_class_constructor() const;
@@ -823,13 +825,13 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
void SetFunctionTokenPosition(int function_token_position,
int start_position);
- static void EnsureBytecodeArrayAvailable(
+ V8_EXPORT_PRIVATE static void EnsureBytecodeArrayAvailable(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
IsCompiledScope* is_compiled_scope,
CreateSourcePositions flag = CreateSourcePositions{false});
inline bool CanCollectSourcePosition(Isolate* isolate);
- static void EnsureSourcePositionsAvailable(
+ V8_EXPORT_PRIVATE static void EnsureSourcePositionsAvailable(
Isolate* isolate, DirectHandle<SharedFunctionInfo> shared_info);
template <typename IsolateT>
@@ -959,9 +961,7 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
inline Tagged<BytecodeArray> GetBytecodeArrayInternal(Isolate* isolate) const;
public:
- // trusted_function_data may point at any concrete ExposedTrustedObject, so
- // the indirect-pointer tag range covers all trusted tags.
- TrustedPointerMember<ExposedTrustedObject, kAllIndirectPointerTags>
+ TrustedPointerMember<ExposedTrustedObject, kTrustedDataIndirectPointerRange>
trusted_function_data_;
TaggedMember<Object> untrusted_function_data_;
TaggedMember<NameOrScopeInfoT> name_or_scope_info_;
diff --git a/deps/v8/src/objects/simd.cc b/deps/v8/src/objects/simd.cc
index 64f76803f17..3ce30aa7fd7 100644
--- a/deps/v8/src/objects/simd.cc
+++ b/deps/v8/src/objects/simd.cc
@@ -922,6 +922,49 @@ void Uint8ArrayToHexFastWithNeon(const char* bytes, uint8_t* output,
HandleRemainingNibbles(bytes, output, length, i);
}
#endif
+
+#ifdef V8_ENABLE_SIMD_SVE
+
+// VLA implementation
+TARGET_SVE void Uint8ArrayToHexFastWithSVE(const uint8_t* bytes,
+ uint8_t* output, size_t length) {
+ const auto all_true_predicate = __builtin_sve_svptrue_pat_b8(sv_all);
+ const uint64_t step = __builtin_sve_svcntb_pat(sv_all);
+ const auto table =
+ __builtin_sve_svdupq_n_u8('0', '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'a', 'b', 'c', 'd', 'e', 'f');
+
+ for (uint64_t i = 0;; i += step) {
+ const auto governing_predicate =
+ __builtin_sve_svwhilelt_b8_u64(i, static_cast<uint64_t>(length));
+
+ if (!__builtin_sve_svptest_first(all_true_predicate, governing_predicate)) {
+ break;
+ }
+
+ const auto input = __builtin_sve_svld1_u8(governing_predicate, bytes + i);
+ // We prefer an all true predicate and we tell the compiler that we don't
+ // care about the predication type (e.g. merging) that is used with the "_x"
+ // variants of the intrinsics, so that it is more likely that the
+ // unpredicated forms of the instructions get generated. The latter do not
+ // depend on the previous values of the outputs.
+ auto high_nibbles =
+ __builtin_sve_svlsr_n_u8_x(all_true_predicate, input, 4);
+ auto low_nibbles =
+ __builtin_sve_svand_n_u8_x(all_true_predicate, input, 0x0F);
+
+ // Map each nibble to a hex digit.
+ high_nibbles = __builtin_sve_svtbl_u8(table, high_nibbles);
+ low_nibbles = __builtin_sve_svtbl_u8(table, low_nibbles);
+ // Interleave both nibble vectors and store.
+ __builtin_sve_svst2_u8(
+ governing_predicate, output + i * 2,
+ __builtin_sve_svcreate2_u8(high_nibbles, low_nibbles));
+ }
+}
+
+#endif // V8_ENABLE_SIMD_SVE
+
} // namespace
Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length,
@@ -943,14 +986,18 @@ Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length,
#ifdef NEON64
if (!is_shared) {
- {
- DCHECK(get_vectorization_kind() == SimdKinds::kNeon ||
- get_vectorization_kind() == SimdKinds::kSVE);
+ DisallowGarbageCollection no_gc;
+ uint8_t* const output = string_output->GetChars(no_gc);
- DisallowGarbageCollection no_gc;
- Uint8ArrayToHexFastWithNeon(bytes, string_output->GetChars(no_gc),
- length);
+#ifdef V8_ENABLE_SIMD_SVE
+ if (get_vectorization_kind() == SimdKinds::kSVE) {
+ Uint8ArrayToHexFastWithSVE(reinterpret_cast<const uint8_t*>(bytes),
+ output, length);
+ return *string_output;
}
+#endif // V8_ENABLE_SIMD_SVE
+
+ Uint8ArrayToHexFastWithNeon(bytes, output, length);
return *string_output;
}
#endif
diff --git a/deps/v8/src/objects/source-text-module.cc b/deps/v8/src/objects/source-text-module.cc
index a11192bf788..0c50a5139d6 100644
--- a/deps/v8/src/objects/source-text-module.cc
+++ b/deps/v8/src/objects/source-text-module.cc
@@ -190,7 +190,11 @@ Tagged<Cell> SourceTextModule::GetCell(int cell_index) {
Handle<Object> SourceTextModule::LoadVariable(
Isolate* isolate, DirectHandle<SourceTextModule> module, int cell_index) {
- return handle(module->GetCell(cell_index)->value(), isolate);
+ Tagged<Object> value = module->GetCell(cell_index)->value();
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(value));
+#endif
+ return handle(value, isolate);
}
void SourceTextModule::StoreVariable(DirectHandle<SourceTextModule> module,
@@ -199,6 +203,9 @@ void SourceTextModule::StoreVariable(DirectHandle<SourceTextModule> module,
DisallowGarbageCollection no_gc;
DCHECK_EQ(SourceTextModuleDescriptor::GetCellIndexKind(cell_index),
SourceTextModuleDescriptor::kExport);
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(*value));
+#endif
module->GetCell(cell_index)->set_value(*value);
}
diff --git a/deps/v8/src/objects/string-inl.h b/deps/v8/src/objects/string-inl.h
index 58c882719ad..00a15364dd4 100644
--- a/deps/v8/src/objects/string-inl.h
+++ b/deps/v8/src/objects/string-inl.h
@@ -832,8 +832,16 @@ template <typename Char>
const Char* String::GetDirectStringChars(
const DisallowGarbageCollection& no_gc V8_LIFETIME_BOUND,
const SharedStringAccessGuardIfNeeded& access_guard) const {
- DCHECK(StringShape(this).IsDirect());
- return StringShape(this).IsExternal()
+ return GetDirectStringChars<Char>(StringShape(this), no_gc, access_guard);
+}
+
+template <typename Char>
+const Char* String::GetDirectStringChars(
+ StringShape shape, const DisallowGarbageCollection& no_gc V8_LIFETIME_BOUND,
+ const SharedStringAccessGuardIfNeeded& access_guard) const {
+ DCHECK(shape.IsValidFor(this));
+ DCHECK(shape.IsDirect());
+ return shape.IsExternal()
? Cast<typename CharTraits<Char>::ExternalString>(this)->GetChars()
: Cast<typename CharTraits<Char>::String>(this)->GetChars(
no_gc, access_guard);
@@ -1484,8 +1492,12 @@ Address ExternalString::resource_as_address() const {
return resource_as_address(isolate);
}
-void ExternalString::set_address_as_resource(Isolate* isolate, Address value) {
- resource_.store(isolate, value);
+void ExternalString::InitResourceDataAfterDeserialization(Isolate* isolate) {
+ if (!is_uncached()) {
+ DCHECK_EQ(resource_data_.load_encoded(), kNullExternalPointer);
+ resource_data_.Init(address(), isolate, kNullAddress);
+ }
+ Address value = resource_as_address(isolate);
if (Is<ExternalOneByteString>(this)) {
Cast<ExternalOneByteString>(this)->update_data_cache(
isolate, reinterpret_cast<ExternalOneByteString::Resource*>(value));
@@ -1495,33 +1507,6 @@ void ExternalString::set_address_as_resource(Isolate* isolate, Address value) {
}
}
-uint32_t ExternalString::GetResourceRefForDeserialization() {
- return static_cast<uint32_t>(resource_.load_encoded());
-}
-
-ExternalString::ResourceRefs ExternalString::SetResourceRefForSerialization(
- uint32_t ref) {
- ResourceRefs refs{resource_.load_encoded(), kNullExternalPointer};
- resource_.store_encoded(static_cast<ExternalPointer_t>(ref));
- if (is_uncached()) return refs;
- refs.resource_data = resource_data_.load_encoded();
- resource_data_.store_encoded(kNullExternalPointer);
- return refs;
-}
-
-void ExternalString::RestoreResourceRefs(Isolate* isolate, ResourceRefs refs) {
-#ifdef V8_ENABLE_SANDBOX
- // The external pointer table entries are not freed while the string is
- // serialized, only the in-object handle fields are overwritten, so re-storing
- // the saved handles re-links the string with its existing entries.
- resource_.store_encoded(refs.resource);
- if (is_uncached()) return;
- resource_data_.store_encoded(refs.resource_data);
-#else
- set_address_as_resource(isolate, static_cast<Address>(refs.resource));
-#endif
-}
-
void ExternalString::DisposeResource(Isolate* isolate) {
DisallowGarbageCollection no_gc;
@@ -1571,6 +1556,12 @@ void ExternalOneByteString::set_resource(
}
}
+const ExternalOneByteString::Resource* ExternalOneByteString::ExchangeResource(
+ Isolate* isolate, const ExternalOneByteString::Resource* resource) {
+ return reinterpret_cast<const Resource*>(
+ resource_.exchange(isolate, reinterpret_cast<Address>(resource)));
+}
+
const uint8_t* ExternalOneByteString::GetChars() const {
DisallowGarbageCollection no_gc;
auto res = resource();
@@ -1633,6 +1624,12 @@ void ExternalTwoByteString::set_resource(
}
}
+const ExternalTwoByteString::Resource* ExternalTwoByteString::ExchangeResource(
+ Isolate* isolate, const ExternalTwoByteString::Resource* resource) {
+ return reinterpret_cast<const Resource*>(
+ resource_.exchange(isolate, reinterpret_cast<Address>(resource)));
+}
+
const uint16_t* ExternalTwoByteString::GetChars() const {
DisallowGarbageCollection no_gc;
auto res = resource();
diff --git a/deps/v8/src/objects/string-table.cc b/deps/v8/src/objects/string-table.cc
index ebf99c3d15b..f4a6a045190 100644
--- a/deps/v8/src/objects/string-table.cc
+++ b/deps/v8/src/objects/string-table.cc
@@ -5,6 +5,7 @@
#include "src/objects/string-table.h"
#include <atomic>
+#include <span>
#include "src/base/atomicops.h"
#include "src/base/macros.h"
@@ -417,6 +418,8 @@ DirectHandle<InternalizedString> StringTable::LookupString(
bool one_byte_content = false;
if (!Name::IsHashFieldComputed(raw_hash_field)) {
raw_hash_field = flat_string->EnsureRawHash(&one_byte_content);
+ } else if (Name::IsIntegerIndex(raw_hash_field)) {
+ one_byte_content = true;
}
InternalizedStringKey key(flat_string, raw_hash_field, one_byte_content);
result = LookupKey(isolate, &key);
@@ -606,18 +609,12 @@ namespace {
template <typename Char>
class CharBuffer {
public:
- void Reset(size_t length) {
+ std::span<Char> Reset(size_t length) V8_LIFETIME_BOUND {
if (length >= kInlinedBufferSize) {
outofline_ = std::make_unique<Char[]>(length);
+ return {outofline_.get(), length};
}
- }
-
- Char* Data() {
- if (outofline_) {
- return outofline_.get();
- } else {
- return inlined_;
- }
+ return {inlined_, length};
}
private:
@@ -625,6 +622,50 @@ class CharBuffer {
Char inlined_[kInlinedBufferSize];
std::unique_ptr<Char[]> outofline_;
};
+
+// Copies `sink.size()` characters of the direct string `str`, whose shape is
+// `shape`, into `sink`.
+template <typename Char>
+V8_INLINE void CopyDirectStringChars(
+ std::span<Char> sink, Tagged<String> str, StringShape shape,
+ const DisallowGarbageCollection& no_gc,
+ const SharedStringAccessGuardIfNeeded& access_guard) {
+ // Even if `sizeof(Char) == 1`, we must check `shape.IsOneByte()` here
+ // because in-sandbox corruption can attach a two-byte child to a one-byte
+ // ConsString, and calling `GetDirectStringChars<uint8_t>` on a two-byte
+ // ExternalString would cause type confusion on the ExternalStringResource.
+ if (shape.IsOneByte()) {
+ CopyChars(sink.data(),
+ str->GetDirectStringChars<uint8_t>(shape, no_gc, access_guard),
+ sink.size());
+ } else {
+ CopyChars(sink.data(),
+ str->GetDirectStringChars<uint16_t>(shape, no_gc, access_guard),
+ sink.size());
+ }
+}
+
+template <typename Char>
+V8_INLINE bool TryCopyConsStringDirect(
+ Tagged<ConsString> cons, std::span<Char> sink,
+ const DisallowGarbageCollection& no_gc,
+ const SharedStringAccessGuardIfNeeded& access_guard) {
+ Tagged<String> first = cons->first();
+ Tagged<String> second = cons->second();
+ const StringShape first_shape(first);
+ const StringShape second_shape(second);
+ if (!first_shape.IsDirect() || !second_shape.IsDirect()) {
+ return false;
+ }
+ const uint32_t first_length = first->length();
+ DCHECK_EQ(sink.size(), first_length + second->length());
+ CopyDirectStringChars(sink.first(first_length), first, first_shape, no_gc,
+ access_guard);
+ CopyDirectStringChars(sink.subspan(first_length), second, second_shape, no_gc,
+ access_guard);
+ return true;
+}
+
} // namespace
// static
@@ -662,9 +703,14 @@ Address StringTable::Data::TryStringToIndexOrLookupExisting(
SharedStringAccessGuardIfNeeded access_guard(isolate);
if (IsConsString(source)) {
DCHECK(!source->IsFlat());
- buffer.Reset(length);
- String::WriteToFlat(source, buffer.Data(), 0, length, access_guard);
- chars = buffer.Data();
+ DCHECK_EQ(start, 0u);
+ DCHECK_EQ(length, source->length());
+ std::span<Char> dest = buffer.Reset(length);
+ if (!TryCopyConsStringDirect<Char>(Cast<ConsString>(source), dest, no_gc,
+ access_guard)) {
+ String::WriteToFlat(source, dest.data(), 0, length, access_guard);
+ }
+ chars = dest.data();
} else {
chars = source->GetDirectStringChars<Char>(no_gc, access_guard) + start;
}
diff --git a/deps/v8/src/objects/string.cc b/deps/v8/src/objects/string.cc
index ccce48db658..429cf2d2134 100644
--- a/deps/v8/src/objects/string.cc
+++ b/deps/v8/src/objects/string.cc
@@ -95,12 +95,13 @@ void MigrateExternalStringResource(Isolate* isolate,
if (to_resource_address == kNullAddress) {
Tagged<StringClass> cast_from = Cast<StringClass>(from);
// |to| is a just-created internalized copy of |from|. Migrate the resource.
- to->SetResource(isolate, cast_from->resource());
+ const typename StringClass::Resource* resource =
+ cast_from->ExchangeResource(isolate, nullptr);
+ to->SetResource(isolate, resource);
// Zap |from|'s resource pointer to reflect the fact that |from| has
// relinquished ownership of its resource.
isolate->heap()->UpdateExternalString(
from, Cast<ExternalString>(from)->ExternalPayloadSize(), 0);
- cast_from->SetResource(isolate, nullptr);
} else if (to_resource_address != from->resource_as_address(isolate)) {
// |to| already existed and has its own resource. Finalize |from|.
isolate->heap()->FinalizeExternalString(from);
diff --git a/deps/v8/src/objects/string.h b/deps/v8/src/objects/string.h
index 5e435ab8e3c..c23650b0a5f 100644
--- a/deps/v8/src/objects/string.h
+++ b/deps/v8/src/objects/string.h
@@ -237,6 +237,14 @@ V8_OBJECT class String : public Name {
const DisallowGarbageCollection& no_gc V8_LIFETIME_BOUND,
const SharedStringAccessGuardIfNeeded& access_guard) const;
+ // Get chars from sequential or external strings. For callers that already
+ // have this string's shape at hand, avoiding a redundant map load.
+ template <typename Char>
+ inline const Char* GetDirectStringChars(
+ StringShape shape,
+ const DisallowGarbageCollection& no_gc V8_LIFETIME_BOUND,
+ const SharedStringAccessGuardIfNeeded& access_guard) const;
+
// Returns the address of the character at an offset into this string.
// Requires: this->IsFlat()
const uint8_t* AddressOfCharacterAt(uint32_t start_index,
@@ -1263,16 +1271,7 @@ V8_OBJECT class ExternalString : public UncachedExternalString {
inline Address resource_as_address(Isolate* isolate) const;
// TODO(pthier): Pass isolate from all callers and remove this overload.
inline Address resource_as_address() const;
- inline void set_address_as_resource(Isolate* isolate, Address address);
- inline uint32_t GetResourceRefForDeserialization();
- // The previous contents of the external pointer fields, as returned by
- // SetResourceRefForSerialization() and put back by RestoreResourceRefs().
- struct ResourceRefs {
- ExternalPointer_t resource;
- ExternalPointer_t resource_data;
- };
- inline ResourceRefs SetResourceRefForSerialization(uint32_t ref);
- inline void RestoreResourceRefs(Isolate* isolate, ResourceRefs refs);
+ inline void InitResourceDataAfterDeserialization(Isolate* isolate);
// Disposes string's resource object if it has not already been disposed.
inline void DisposeResource(Isolate* isolate);
@@ -1322,6 +1321,9 @@ V8_OBJECT class ExternalOneByteString : public ExternalString {
// Used only during serialization.
inline void set_resource(Isolate* isolate, const Resource* buffer);
+ inline const Resource* ExchangeResource(Isolate* isolate,
+ const Resource* resource);
+
// Update the pointer cache to the external character array.
// The cached pointer is always valid, as the external character array does =
// not move during lifetime. Deserialization is the only exception, after
@@ -1358,6 +1360,9 @@ V8_OBJECT class ExternalTwoByteString : public ExternalString {
// Used only during serialization.
inline void set_resource(Isolate* isolate, const Resource* buffer);
+ inline const Resource* ExchangeResource(Isolate* isolate,
+ const Resource* resource);
+
// Update the pointer cache to the external character array.
// The cached pointer is always valid, as the external character array does =
// not move during lifetime. Deserialization is the only exception, after
diff --git a/deps/v8/src/objects/transitions.cc b/deps/v8/src/objects/transitions.cc
index ec887071a14..907e8e695b5 100644
--- a/deps/v8/src/objects/transitions.cc
+++ b/deps/v8/src/objects/transitions.cc
@@ -414,6 +414,7 @@ bool TransitionsAccessor::PutPrototypeTransition(Isolate* isolate,
DirectHandle<Object> prototype,
DirectHandle<Map> target_map) {
DCHECK(IsUndefined(map->GetBackPointer()));
+ DCHECK_NE(map->prototype(), *prototype);
DCHECK(IsMap(Cast<HeapObject>(*prototype)->map()));
// Only the main thread should write to transition arrays.
diff --git a/deps/v8/src/objects/trusted-object-inl.h b/deps/v8/src/objects/trusted-object-inl.h
index 9657f7f7ac7..fa361c96798 100644
--- a/deps/v8/src/objects/trusted-object-inl.h
+++ b/deps/v8/src/objects/trusted-object-inl.h
@@ -107,7 +107,8 @@ void ExposedTrustedObject::InitDontPublish(Isolate* isolate) {
#ifdef V8_ENABLE_SANDBOX
i::InitSelfIndirectPointerField(
reinterpret_cast<Address>(&self_indirect_pointer_), isolate, this,
- kUnpublishedIndirectPointerTag, nullptr);
+ kUnpublishedIndirectPointerTag,
+ isolate->trusted_pointer_publishing_scope());
#endif
}
diff --git a/deps/v8/src/objects/value-serializer.cc b/deps/v8/src/objects/value-serializer.cc
index 2c3434f3de2..36a784bcbf5 100644
--- a/deps/v8/src/objects/value-serializer.cc
+++ b/deps/v8/src/objects/value-serializer.cc
@@ -2199,10 +2199,13 @@ MaybeDirectHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer(
DirectHandle<Object> wasm_memory_obj;
if (!ReadObject().ToHandle(&wasm_memory_obj)) return {};
if (!IsWasmMemoryObject(*wasm_memory_obj)) return {};
- // If the WasmMemoryObject was deserialized just now, it will have set
- // up the link from the ArrayBuffer already. If it was reused
- // (deserialized earlier), then we need to establish a link from this
- // second AB.
+ // If this ArrayBuffer is the WasmMemoryObject's primary buffer,
+ // WasmMemoryObject::SetNewBuffer will also fix it up and set the link.
+ // If it is not the primary buffer (e.g. displaced by
+ // toFixedLengthBuffer()), we must fix up max_byte_length and establish
+ // the link to the WasmMemoryObject here.
+ Cast<WasmMemoryObject>(*wasm_memory_obj)
+ ->FixUpResizableArrayBuffer(*array_buffer);
Object::SetProperty(
isolate_, array_buffer,
isolate_->factory()->array_buffer_wasm_memory_symbol(),
@@ -2600,6 +2603,8 @@ MaybeDirectHandle<HeapObject> ValueDeserializer::ReadSharedObject() {
STACK_CHECK(isolate_, MaybeDirectHandle<HeapObject>());
DCHECK_GE(version_, 15);
+ uint32_t id = next_id_++;
+
uint32_t shared_object_id;
if (!ReadVarint<uint32_t>().To(&shared_object_id)) {
RETURN_EXCEPTION_IF_EXCEPTION(isolate_);
@@ -2624,6 +2629,7 @@ MaybeDirectHandle<HeapObject> ValueDeserializer::ReadSharedObject() {
DirectHandle<HeapObject> shared_object(
shared_object_conveyor_->GetPersisted(shared_object_id), isolate_);
DCHECK(IsShared(*shared_object));
+ AddObjectWithID(id, Cast<JSReceiver>(shared_object));
return shared_object;
}
diff --git a/deps/v8/src/parsing/parse-info.cc b/deps/v8/src/parsing/parse-info.cc
index ae0644a059c..f33708abdf8 100644
--- a/deps/v8/src/parsing/parse-info.cc
+++ b/deps/v8/src/parsing/parse-info.cc
@@ -39,6 +39,7 @@ UnoptimizedCompileFlags::UnoptimizedCompileFlags(Isolate* isolate,
v8_flags.parallel_compile_tasks_for_eager_toplevel);
set_post_parallel_compile_tasks_for_lazy(
v8_flags.parallel_compile_tasks_for_lazy);
+ set_allow_heap_allocation(true);
}
// static
@@ -73,10 +74,6 @@ UnoptimizedCompileFlags UnoptimizedCompileFlags::ForScriptCompile(
: ScriptType::kClassic,
v8_flags.lazy);
flags.set_outer_language_mode(script->outer_language_mode());
- if (script->compilation_kind() ==
- Script::CompilationKind::kFunctionConstructor) {
- flags.set_parse_restriction(ONLY_SINGLE_FUNCTION_LITERAL);
- }
flags.SetFlagsForFunctionFromScript(script);
if (script->is_wrapped()) {
flags.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
@@ -157,6 +154,10 @@ void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(
set_block_coverage_enabled(block_coverage_enabled() &&
script->IsUserJavaScript());
+ if (is_toplevel() && script->compilation_kind() ==
+ Script::CompilationKind::kFunctionConstructor) {
+ set_parse_restriction(ONLY_SINGLE_FUNCTION_LITERAL);
+ }
}
ReusableUnoptimizedCompileState::ReusableUnoptimizedCompileState(
@@ -211,8 +212,7 @@ ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
language_mode_(flags.outer_language_mode()),
is_background_compilation_(false),
is_streaming_compilation_(false),
- has_module_in_scope_chain_(flags.is_module()),
- has_generator_in_scope_chain_(false) {
+ has_module_in_scope_chain_(flags.is_module()) {
if (flags.block_coverage_enabled()) {
AllocateSourceRangeMap();
}
diff --git a/deps/v8/src/parsing/parse-info.h b/deps/v8/src/parsing/parse-info.h
index 65da7d537d9..ef6f4f577ee 100644
--- a/deps/v8/src/parsing/parse-info.h
+++ b/deps/v8/src/parsing/parse-info.h
@@ -65,7 +65,8 @@ class Zone;
V(produce_compile_hints, bool, 1, _) \
V(compile_hints_magic_enabled, bool, 1, _) \
V(compile_hints_per_function_magic_enabled, bool, 1, _) \
- V(is_hoisted_in_context, bool, 1, _)
+ V(is_hoisted_in_context, bool, 1, _) \
+ V(allow_heap_allocation, bool, 1, _)
class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
public:
@@ -347,13 +348,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
bool has_module_in_scope_chain() const { return has_module_in_scope_chain_; }
void set_has_module_in_scope_chain() { has_module_in_scope_chain_ = true; }
- bool has_generator_in_scope_chain() const {
- return has_generator_in_scope_chain_;
- }
- void set_has_generator_in_scope_chain() {
- has_generator_in_scope_chain_ = true;
- }
-
void SetCompileHintCallbackAndData(CompileHintCallback callback, void* data) {
DCHECK_NULL(compile_hint_callback_);
DCHECK_NULL(compile_hint_callback_data_);
@@ -404,7 +398,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
bool is_background_compilation_ : 1;
bool is_streaming_compilation_ : 1;
bool has_module_in_scope_chain_ : 1;
- bool has_generator_in_scope_chain_ : 1;
};
} // namespace internal
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index 54dde689b45..5b552c58379 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -254,7 +254,6 @@ class ParserBase {
: scope_(nullptr),
original_scope_(nullptr),
function_state_(nullptr),
- has_generator_in_scope_chain_(false),
fni_(ast_value_factory),
ast_value_factory_(ast_value_factory),
ast_node_factory_(ast_value_factory, zone),
@@ -280,13 +279,6 @@ class ParserBase {
const UnoptimizedCompileFlags& flags() const { return flags_; }
bool has_module_in_scope_chain() const { return has_module_in_scope_chain_; }
- bool has_generator_in_scope_chain() const {
- return has_generator_in_scope_chain_;
- }
- void set_has_generator_in_scope_chain(bool has_generator) {
- has_generator_in_scope_chain_ = has_generator;
- }
-
// DebugEvaluate code
bool IsParsingWhileDebugging() const {
return flags().parsing_while_debugging() == ParsingWhileDebugging::kYes;
@@ -458,7 +450,7 @@ class ParserBase {
class FunctionState final : public BlockState {
public:
FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
- DeclarationScope* scope, bool* has_generator_in_scope_chain);
+ DeclarationScope* scope);
~FunctionState();
DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
@@ -558,9 +550,6 @@ class ParserBase {
// Track if a function or eval occurs within this FunctionState
bool contains_function_or_eval_;
- bool* has_generator_in_scope_chain_ptr_;
- bool previous_has_generator_in_scope_chain_;
-
friend Impl;
};
@@ -1763,7 +1752,6 @@ class ParserBase {
Scope* object_literal_scope_ = nullptr;
Scope* original_scope_; // The top scope for the current parsing item.
FunctionState* function_state_; // Function state stack.
- bool has_generator_in_scope_chain_;
FuncNameInferrer fni_;
AstValueFactory* ast_value_factory_; // Not owned.
typename Types::Factory ast_node_factory_;
@@ -1845,7 +1833,7 @@ class ParserBase {
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
FunctionState** function_state_stack, Scope** scope_stack,
- DeclarationScope* scope, bool* has_generator_in_scope_chain)
+ DeclarationScope* scope)
: BlockState(scope_stack, scope),
expected_property_count_(0),
suspend_count_(0),
@@ -1855,23 +1843,18 @@ ParserBase<Impl>::FunctionState::FunctionState(
dont_optimize_reason_(BailoutReason::kNoReason),
next_function_is_likely_called_(false),
previous_function_was_likely_called_(false),
- contains_function_or_eval_(false),
- has_generator_in_scope_chain_ptr_(has_generator_in_scope_chain),
- previous_has_generator_in_scope_chain_(*has_generator_in_scope_chain) {
+ contains_function_or_eval_(false) {
*function_state_stack = this;
if (outer_function_state_) {
outer_function_state_->previous_function_was_likely_called_ =
outer_function_state_->next_function_is_likely_called_;
outer_function_state_->next_function_is_likely_called_ = false;
}
- *has_generator_in_scope_chain_ptr_ =
- previous_has_generator_in_scope_chain_ || IsGeneratorFunction(kind());
}
template <typename Impl>
ParserBase<Impl>::FunctionState::~FunctionState() {
*function_state_stack_ = outer_function_state_;
- *has_generator_in_scope_chain_ptr_ = previous_has_generator_in_scope_chain_;
}
template <typename Impl>
@@ -2522,14 +2505,12 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
if (prop_info->kind == ParsePropertyKind::kNotSet &&
base::IsInRange(peek(), Token::kGet, Token::kSet)) {
Token::Value token = Next();
- if (prop_info->ParsePropertyKindFromToken(peek())) {
+ if (prop_info->ParsePropertyKindFromToken(peek()) ||
+ V8_UNLIKELY(scanner()->literal_contains_escapes())) {
prop_info->name = impl()->GetIdentifier();
impl()->PushLiteralName(prop_info->name);
return factory()->NewStringLiteral(prop_info->name, position());
}
- if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
- impl()->ReportUnexpectedToken(Token::kEscapedKeyword);
- }
if (token == Token::kGet) {
prop_info->kind = ParsePropertyKind::kAccessorGetter;
} else if (token == Token::kSet) {
@@ -2906,8 +2887,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
if (Check(Token::kAssign)) {
FunctionState initializer_state(&function_state_, &scope_,
- initializer_scope,
- &has_generator_in_scope_chain_);
+ initializer_scope);
AcceptINScope scope(this, true);
auto result = ParseAssignmentExpression();
@@ -2926,8 +2906,7 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseClassStaticBlock(
DeclarationScope* initializer_scope =
class_info->EnsureStaticElementsScope(this, position(), PeekNextInfoId());
- FunctionState initializer_state(&function_state_, &scope_, initializer_scope,
- &has_generator_in_scope_chain_);
+ FunctionState initializer_state(&function_state_, &scope_, initializer_scope);
FunctionParsingScope body_parsing_scope(impl());
AcceptINScope accept_in(this, true);
@@ -5147,8 +5126,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
StatementListT body(pointer_buffer());
{
FunctionState function_state(&function_state_, &scope_,
- formal_parameters.scope,
- &has_generator_in_scope_chain_);
+ formal_parameters.scope);
Consume(Token::kArrow);
@@ -5196,8 +5174,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
DeclarationScope* function_scope = next_arrow_function_info_.scope;
FunctionState inner_function_state(&function_state_, &scope_,
- function_scope,
- &has_generator_in_scope_chain_);
+ function_scope);
Scanner::Location loc(function_scope->start_position(),
end_position());
FormalParametersT parameters(function_scope);
@@ -5369,6 +5346,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
if (should_save_class_variable) {
class_scope->class_variable()->set_is_used();
class_scope->class_variable()->ForceContextAllocation();
+ // Static brand checks elide the hole check and can observe `the_hole`
+ // before the class is initialized. Mark as assigned so `the_hole` is not
+ // propagated across initialization.
+ class_scope->class_variable()->set_maybe_assigned();
}
}
@@ -6534,17 +6515,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
Consume(Token::kTry);
int pos = position();
- std::optional<typename Scope::Snapshot> try_catch_snapshot;
- if (has_generator_in_scope_chain()) {
- try_catch_snapshot.emplace(scope());
- }
-
BlockT try_block = ParseBlock(nullptr);
- if (try_catch_snapshot.has_value()) {
- try_catch_snapshot->MarkUnresolvedVariablesAsInsideTryCatch();
- }
-
CatchInfo catch_info(this);
if (peek() != Token::kCatch && peek() != Token::kFinally) {
@@ -6648,7 +6620,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
}
RETURN_IF_PARSE_ERROR;
-
return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
finally_block, finally_range, catch_info,
pos);
diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc
index 00dab82d04b..94f19994ccf 100644
--- a/deps/v8/src/parsing/parser.cc
+++ b/deps/v8/src/parsing/parser.cc
@@ -55,8 +55,7 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
ScopedPtrList<Statement> body(pointer_buffer());
{
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
// https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation
//
@@ -100,12 +99,12 @@ FunctionLiteral* Parser::MakeAutoAccessorGetter(VariableProxy* name_proxy,
function_scope->set_start_position(pos);
function_scope->set_end_position(pos);
{
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
body.Add(factory()->NewAutoAccessorGetterBody(name_proxy, pos));
}
// TODO(42202709): Enable lazy compilation by adding custom handling in
// `Parser::DoParseFunction`.
+ function_scope->set_force_eager_compilation(true);
FunctionLiteral* getter = factory()->NewFunctionLiteral(
nullptr, function_scope, body, 0, 0, 0,
FunctionLiteral::kNoDuplicateParameters,
@@ -131,12 +130,12 @@ FunctionLiteral* Parser::MakeAutoAccessorSetter(VariableProxy* name_proxy,
VariableMode::kTemporary, false, false,
ast_value_factory(), kNoSourcePosition);
{
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
body.Add(factory()->NewAutoAccessorSetterBody(name_proxy, pos));
}
// TODO(42202709): Enable lazy compilation by adding custom handling in
// `Parser::DoParseFunction`.
+ function_scope->set_force_eager_compilation(true);
FunctionLiteral* setter = factory()->NewFunctionLiteral(
nullptr, function_scope, body, 0, 1, 0,
FunctionLiteral::kNoDuplicateParameters,
@@ -617,7 +616,10 @@ Parser::Parser(LocalIsolate* local_isolate, ParseInfo* info)
total_preparse_skipped_(0),
consumed_preparse_data_(info->consumed_preparse_data()),
preparse_data_buffer_(),
- parameters_end_pos_(info->parameters_end_pos()) {
+ parameters_end_pos_(info->parameters_end_pos()),
+ parsing_dynamic_function_declaration_(
+ info->parameters_end_pos() != kNoSourcePosition ||
+ info->flags().parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
// Even though we were passed ParseInfo, we should not store it in
// Parser - this makes sure that Isolate is not accidentally accessed via
// ParseInfo during background parsing.
@@ -691,9 +693,6 @@ void Parser::DeserializeScopeChain(
if (info->has_module_in_scope_chain()) {
set_has_module_in_scope_chain();
}
- if (info->has_generator_in_scope_chain()) {
- set_has_generator_in_scope_chain(true);
- }
}
}
@@ -747,14 +746,18 @@ void Parser::ParseProgram(Isolate* isolate, DirectHandle<Script> script,
scanner_.Initialize();
FunctionLiteral* result =
DoParseProgram(isolate, info, script->eval_from_position());
- HandleDebugMagicComments(isolate, script);
+ if (flags().allow_heap_allocation()) {
+ HandleDebugMagicComments(isolate, script);
+ }
if (result == nullptr) return;
result->scope()->set_is_hoisted_in_context(
info->flags().is_hoisted_in_context());
- MaybeProcessSourceRanges(info, result, stack_limit_);
+ if (flags().allow_heap_allocation()) {
+ MaybeProcessSourceRanges(info, result, stack_limit_);
+ }
PostProcessParseResult(isolate, info, result);
- if (V8_UNLIKELY(v8_flags.log_function_events)) {
+ if (V8_UNLIKELY(v8_flags.log_function_events) && !flags().is_reparse()) {
double ms = timer.Elapsed().InMillisecondsF();
const char* event_name = "parse-eval";
int start = -1;
@@ -798,8 +801,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info,
DeclarationScope* scope = outer->AsDeclarationScope();
scope->set_start_position(0);
- FunctionState function_state(&function_state_, &scope_, scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, scope);
ScopedPtrList<Statement> body(pointer_buffer());
int beg_pos = scanner()->location().beg_pos;
if (flags().is_module()) {
@@ -850,12 +852,14 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info,
}
// Internalize the ast strings in the case of eval so we can check for
// conflicting var declarations with outer scope-info-backed scopes.
- if (flags().is_eval()) {
- DCHECK(parsing_on_main_thread_);
- DCHECK(!isolate->main_thread_local_heap()->IsParked());
- info->ast_value_factory()->Internalize(isolate);
+ if (flags().allow_heap_allocation()) {
+ if (flags().is_eval()) {
+ DCHECK(parsing_on_main_thread_);
+ DCHECK(!isolate->main_thread_local_heap()->IsParked());
+ info->ast_value_factory()->Internalize(isolate);
+ }
+ CheckConflictingVarDeclarations(scope);
}
- CheckConflictingVarDeclarations(scope);
// For sloppy eval though, we clear dynamic variables created for toplevel
// var to avoid resolving to a variable when the variable and proxy are in
@@ -900,7 +904,9 @@ void Parser::PostProcessParseResult(IsolateT* isolate, ParseInfo* info,
info->set_allow_eval_cache(allow_eval_cache());
}
- info->ast_value_factory()->Internalize(isolate);
+ if (flags().allow_heap_allocation()) {
+ info->ast_value_factory()->Internalize(isolate);
+ }
{
RCS_SCOPE(info->runtime_call_stats(), RuntimeCallCounterId::kCompileAnalyse,
@@ -965,8 +971,7 @@ void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
// Set function and block state for the outer eval scope.
DCHECK(outer_scope->is_eval_scope());
- FunctionState function_state(&function_state_, &scope_, outer_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, outer_scope);
const AstRawString* function_name = nullptr;
Scanner::Location location(0, 0);
@@ -1160,8 +1165,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
Scope* outer = original_scope_;
DeclarationScope* outer_function = outer->GetClosureScope();
DCHECK(outer);
- FunctionState function_state(&function_state_, &scope_, outer_function,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, outer_function);
BlockState block_state(&scope_, outer);
DCHECK(is_sloppy(outer->language_mode()) ||
is_strict(info->language_mode()));
@@ -1273,8 +1277,7 @@ FunctionLiteral* Parser::ParseClassForMemberInitialization(
// Insert a FunctionState with the closest outer Declaration scope
DeclarationScope* nearest_decl_scope = original_scope_->GetDeclarationScope();
DCHECK_NOT_NULL(nearest_decl_scope);
- FunctionState function_state(&function_state_, &scope_, nearest_decl_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, nearest_decl_scope);
// We preparse the class members that are not fields with initializers
// in order to collect the function literal ids.
@@ -2833,13 +2836,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
function_name = ast_value_factory()->empty_string();
}
- // This is true if we get here through CreateDynamicFunction.
- bool params_need_validation = parameters_end_pos_ != kNoSourcePosition;
int compile_hint_position = peek_position();
FunctionLiteral::EagerCompileHint eager_compile_hint =
function_state_->next_function_is_likely_called() || is_wrapped ||
- params_need_validation ||
+ parsing_dynamic_function_declaration_ ||
(info()->flags().compile_hints_magic_enabled() &&
scanner()->SawMagicCommentCompileHintsAll()) ||
(info()->flags().compile_hints_per_function_magic_enabled() &&
@@ -3042,8 +3043,7 @@ bool Parser::SkipFunction(int function_literal_id,
DeclarationScope* function_scope, int* num_parameters,
int* function_length,
ProducedPreparseData** produced_preparse_data) {
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
function_scope->set_zone(&preparser_zone_);
DCHECK_NE(kNoSourcePosition, function_scope->start_position());
@@ -3096,8 +3096,6 @@ bool Parser::SkipFunction(int function_literal_id,
// AST. This gathers the data needed to build a lazy function.
TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
- reusable_preparser()->set_has_generator_in_scope_chain(
- has_generator_in_scope_chain());
reusable_preparser()->set_max_drift(this->max_drift());
PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
function_literal_id, function_name, kind, function_syntax_kind,
@@ -3202,15 +3200,15 @@ void Parser::ParseFunction(
ScopedModification<Mode> mode_scope(
&mode_, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
bool is_wrapped = function_syntax_kind == FunctionSyntaxKind::kWrapped;
int expected_parameters_end_pos = parameters_end_pos_;
- if (expected_parameters_end_pos != kNoSourcePosition) {
+ if (parsing_dynamic_function_declaration_) {
// This is the first function encountered in a CreateDynamicFunction eval.
parameters_end_pos_ = kNoSourcePosition;
+ parsing_dynamic_function_declaration_ = false;
// The function name should have been ignored, giving us the empty string
// here.
DCHECK_EQ(function_name, ast_value_factory()->empty_string());
diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h
index 0a52155db3b..5226a2ccea6 100644
--- a/deps/v8/src/parsing/parser.h
+++ b/deps/v8/src/parsing/parser.h
@@ -913,7 +913,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// Returns true iff we're parsing the first function literal during
// CreateDynamicFunction().
V8_INLINE bool ParsingDynamicFunctionDeclaration() const {
- return parameters_end_pos_ != kNoSourcePosition;
+ return parsing_dynamic_function_declaration_;
}
V8_INLINE void ConvertBinaryToNaryOperationSourceRange(
@@ -1134,6 +1134,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// indicates the correct position of the ')' that closes the parameter list.
// After that ')' is encountered, this field is reset to kNoSourcePosition.
int parameters_end_pos_;
+ bool parsing_dynamic_function_declaration_;
};
} // namespace internal
diff --git a/deps/v8/src/parsing/preparse-data.cc b/deps/v8/src/parsing/preparse-data.cc
index 65d6a6cb5d5..451f557198e 100644
--- a/deps/v8/src/parsing/preparse-data.cc
+++ b/deps/v8/src/parsing/preparse-data.cc
@@ -691,6 +691,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
}
var->set_is_used();
var->ForceContextAllocation();
+ var->set_maybe_assigned();
scope->AsClassScope()->set_should_save_class_variable();
}
diff --git a/deps/v8/src/parsing/preparse-data.h b/deps/v8/src/parsing/preparse-data.h
index ba081c736d1..b419bb3c0f1 100644
--- a/deps/v8/src/parsing/preparse-data.h
+++ b/deps/v8/src/parsing/preparse-data.h
@@ -89,8 +89,12 @@ struct PreparseByteDataConstants {
static const size_t kSkippableFunctionMinDataSize =
4 * kVarint32MinSize + 1 * kUint8Size;
+ // A skippable function writes up to 5 Varint32s (start_position,
+ // end_position, has_data_and_num_parameters, function_length when
+ // length != num_parameters, and num_inner_functions) plus 1 Quarter
+ // (language_and_super).
static const size_t kSkippableFunctionMaxDataSize =
- 4 * kVarint32MaxSize + 1 * kUint8Size;
+ 5 * kVarint32MaxSize + 1 * kUint8Size;
};
class V8_EXPORT_PRIVATE PreparseDataBuilder : public ZoneObject,
diff --git a/deps/v8/src/parsing/preparser.cc b/deps/v8/src/parsing/preparser.cc
index 1be7edce850..997657fba13 100644
--- a/deps/v8/src/parsing/preparser.cc
+++ b/deps/v8/src/parsing/preparser.cc
@@ -73,8 +73,7 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
// the global scope.
if (flags().is_module()) scope = NewModuleScope(scope);
- FunctionState top_scope(&function_state_, &scope_, scope,
- &has_generator_in_scope_chain_);
+ FunctionState top_scope(&function_state_, &scope_, scope);
original_scope_ = scope_;
int start_position = peek_position();
PreParserScopedStatementList body(pointer_buffer());
@@ -116,8 +115,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
// PreParser.
DCHECK_NULL(function_state_);
DCHECK_NULL(scope_);
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
// Start collecting data for a new function which might contain skippable
// functions.
@@ -291,8 +289,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
preparse_data_builder_scope.Start(function_scope);
}
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
Expect(Token::kLeftParen);
int start_position = position();
diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h
index a1b10511bcd..beef2b93234 100644
--- a/deps/v8/src/parsing/preparser.h
+++ b/deps/v8/src/parsing/preparser.h
@@ -1188,8 +1188,7 @@ class PreParser : public ParserBase<PreParser> {
SetLanguageMode(function_scope, LanguageMode::kStrict);
function_scope->set_start_position(pos);
function_scope->set_end_position(pos);
- FunctionState function_state(&function_state_, &scope_, function_scope,
- &has_generator_in_scope_chain_);
+ FunctionState function_state(&function_state_, &scope_, function_scope);
GetNextInfoId();
}
diff --git a/deps/v8/src/profiler/cpu-profiler.cc b/deps/v8/src/profiler/cpu-profiler.cc
index 5c3955fb9be..0204463acb2 100644
--- a/deps/v8/src/profiler/cpu-profiler.cc
+++ b/deps/v8/src/profiler/cpu-profiler.cc
@@ -570,6 +570,7 @@ CpuProfiler::~CpuProfiler() {
void CpuProfiler::set_sampling_interval(base::TimeDelta value) {
DCHECK(!is_profiling_);
+ DCHECK_GE(value, base::TimeDelta());
base_sampling_interval_ = value;
}
diff --git a/deps/v8/src/profiler/heap-profiler.cc b/deps/v8/src/profiler/heap-profiler.cc
index f7598197881..603fd18e877 100644
--- a/deps/v8/src/profiler/heap-profiler.cc
+++ b/deps/v8/src/profiler/heap-profiler.cc
@@ -130,10 +130,7 @@ HeapSnapshot* HeapProfiler::TakeSnapshot(
// The garbage collection and the filling of references in GenerateSnapshot
// should scan the same part of the stack.
heap()->stack().SetMarkerIfNeededAndCallback([this, &options, &result]() {
- std::optional<CppClassNamesAsHeapObjectNameScope> use_cpp_class_name;
- if (heap()->cpp_heap()) {
- use_cpp_class_name.emplace(heap()->cpp_heap());
- }
+ CppClassNamesAsHeapObjectNameScope use_cpp_class_name(heap()->cpp_heap());
HeapSnapshotGenerator generator(result, options.control,
options.context_name_resolver, heap(),
@@ -236,6 +233,18 @@ void HeapProfiler::StopSamplingHeapProfiler() {
MaybeClearStringsStorage();
}
+void HeapProfiler::SetSamplingHeapProfilerInterval(uint64_t sample_interval) {
+ if (sampling_heap_profiler_) {
+ sampling_heap_profiler_->SetSamplingInterval(sample_interval);
+ }
+}
+
+std::vector<v8::AllocationProfile::Sample>
+HeapProfiler::GetSamplingHeapProfilerSamples() {
+ if (!sampling_heap_profiler_) return {};
+ return sampling_heap_profiler_->GetSamples();
+}
+
v8::AllocationProfile* HeapProfiler::GetAllocationProfile() {
if (sampling_heap_profiler_) {
return sampling_heap_profiler_->GetAllocationProfile();
diff --git a/deps/v8/src/profiler/heap-profiler.h b/deps/v8/src/profiler/heap-profiler.h
index 9f82946bb31..031f32762fa 100644
--- a/deps/v8/src/profiler/heap-profiler.h
+++ b/deps/v8/src/profiler/heap-profiler.h
@@ -83,6 +83,8 @@ class HeapProfiler : public HeapObjectAllocationTracker {
bool StartSamplingHeapProfiler(uint64_t sample_interval, int stack_depth,
v8::HeapProfiler::SamplingFlags);
void StopSamplingHeapProfiler();
+ void SetSamplingHeapProfilerInterval(uint64_t sample_interval);
+ std::vector<v8::AllocationProfile::Sample> GetSamplingHeapProfilerSamples();
bool is_sampling_allocations() { return !!sampling_heap_profiler_; }
AllocationProfile* GetAllocationProfile();
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc
index 1683d0f8430..30994012c4b 100644
--- a/deps/v8/src/profiler/heap-snapshot-generator.cc
+++ b/deps/v8/src/profiler/heap-snapshot-generator.cc
@@ -8,6 +8,9 @@
#include <utility>
#include "src/api/api-inl.h"
+#include "src/ast/ast.h"
+#include "src/ast/scopes.h"
+#include "src/ast/variables.h"
#include "src/base/vector.h"
#include "src/builtins/builtins.h"
#include "src/codegen/assembler-inl.h"
@@ -52,10 +55,15 @@
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/prototype.h"
+#include "src/objects/scope-info.h"
#include "src/objects/slots-inl.h"
#include "src/objects/struct-inl.h"
#include "src/objects/transitions-inl.h"
#include "src/objects/visitors.h"
+#include "src/parsing/parse-info.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/parsing.h"
+#include "src/parsing/scanner-character-streams.h"
#include "src/profiler/allocation-tracker.h"
#include "src/profiler/heap-profiler.h"
#include "src/profiler/output-stream-writer.h"
@@ -71,6 +79,101 @@
namespace v8::internal {
+namespace {
+
+void CollectScopeTree(Scope* scope, int depth, HeapEntry* script_entry,
+ StringsStorage* names, HeapSnapshot* snapshot) {
+ SourceScopeInfo info;
+ info.script_entry = script_entry;
+ info.scope_id = scope->UniqueIdInScript();
+ // We use the depth here to encode the tree hierarchy. The more natural way
+ // would be to use the scope id of the parent scope. However, the scope id can
+ // be negative (currently -1 or -2) or zero, the values we would usually as
+ // "no parent" marker for the root scope. Using depth avois defining such a
+ // magic marker as e.g. -3 or kMaxInt.
+ info.depth = depth;
+
+ std::vector<Variable*> context_vars;
+
+ if (scope->is_class_scope()) {
+ // Class scopes contain private fields and methods for which uses across
+ // closures are currently not tracked. Omit context variables to disable
+ // dead context analysis.
+ } else if (scope->inner_scope_calls_eval()) {
+ // If this scope or any of its inner scopes contains a direct eval call,
+ // variables might be dynamically accessed at runtime. Omit context
+ // variables to disable dead context analysis.
+ } else {
+ // In all other cases record the context-allocated variables.
+ for (Variable* var : *scope->locals()) {
+ if (var->IsContextSlot()) {
+ context_vars.push_back(var);
+ }
+ }
+ std::sort(context_vars.begin(), context_vars.end(),
+ [](Variable* a, Variable* b) { return a->index() < b->index(); });
+ }
+
+ info.scope_context_vars_count = static_cast<uint32_t>(context_vars.size());
+ for (Variable* var : context_vars) {
+ snapshot->AddSourceScopeContextVar(names->GetCopy(var->raw_name()));
+ }
+
+ // Collect all uses of context variables in this scope. Each use is a pair of
+ // declaring scope id and context slot index.
+ size_t uses_start = snapshot->source_scope_uses().size();
+
+ // `this` references are tracked on DeclarationScope via has_this_reference()
+ // rather than remaining in unresolved_list(). If this declaration scope
+ // accesses `this` and it was allocated to a context slot by the receiver
+ // scope, record it as a context variable use.
+ if (scope->is_declaration_scope() &&
+ scope->AsDeclarationScope()->has_this_reference()) {
+ DeclarationScope* receiver_scope =
+ scope->AsDeclarationScope()->GetReceiverScope();
+ Variable* receiver_var = receiver_scope->receiver();
+ if (receiver_var != nullptr && receiver_var->IsContextSlot() &&
+ receiver_var->scope() != nullptr) {
+ Scope* decl_scope = receiver_var->scope();
+ int slot_index =
+ receiver_var->index() - decl_scope->ContextHeaderLength();
+ snapshot->AddSourceScopeUse({decl_scope->UniqueIdInScript(), slot_index});
+ }
+ }
+
+ for (VariableProxy* proxy : scope->unresolved_list()) {
+ if (proxy->is_removed_from_unresolved()) continue;
+ if (proxy->is_resolved() && proxy->var() != nullptr) {
+ Variable* var = proxy->var();
+ // Lookups passing through an intervening scope (e.g. a `with` scope)
+ // are resolved dynamically, but track the outer local variable via
+ // local_if_not_shadowed(). Use the underlying local variable to record
+ // the context use.
+ if (var->is_dynamic() && var->has_local_if_not_shadowed()) {
+ var = var->local_if_not_shadowed();
+ }
+ if (var->IsContextSlot() && var->scope() != nullptr) {
+ Scope* decl_scope = var->scope();
+ int slot_index = var->index() - decl_scope->ContextHeaderLength();
+ snapshot->AddSourceScopeUse(
+ {decl_scope->UniqueIdInScript(), slot_index});
+ }
+ }
+ }
+ info.scope_uses_count =
+ static_cast<uint32_t>(snapshot->source_scope_uses().size() - uses_start);
+
+ snapshot->AddSourceScope(info);
+
+ // Recurse children
+ for (Scope* child = scope->inner_scope(); child != nullptr;
+ child = child->sibling()) {
+ CollectScopeTree(child, depth + 1, script_entry, names, snapshot);
+ }
+}
+
+} // namespace
+
#ifdef V8_ENABLE_HEAP_SNAPSHOT_VERIFY
bool ShouldVerifyReferenceTo(Isolate* isolate, Tagged<HeapObject> obj) {
// We can't verify pointers into read-only space, because marking visitors
@@ -2030,6 +2133,12 @@ void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Tagged<Map> map) {
void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
HeapEntry* entry, Tagged<SharedFunctionInfo> shared) {
TagObject(shared, "(shared function info)");
+#if V8_ENABLE_WEBASSEMBLY
+ // Wasm functions store their wrapper Code on the JSFunction's
+ // JSDispatchTable entry rather than on the SharedFunctionInfo, so
+ // SharedFunctionInfo::GetCode is not applicable to WasmFunctionData.
+ if (!shared->HasWasmFunctionData(isolate()))
+#endif // V8_ENABLE_WEBASSEMBLY
{
std::unique_ptr<char[]> name = shared->DebugNameCStr();
Tagged<Code> code = shared->GetCode(isolate());
@@ -2072,6 +2181,8 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
shared->EndPosition());
AddIntEdge(entry, HeapGraphEdge::kInternal, "function_literal_id",
shared->function_literal_id(kRelaxedLoad));
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "scope_id",
+ shared->UniqueIdInScript());
if (shared->HasBuiltinId()) {
AddIntEdge(entry, HeapGraphEdge::kInternal, "builtin_id",
static_cast<int>(shared->builtin_id()));
@@ -2080,8 +2191,42 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
}
}
+void V8HeapExplorer::ParseScriptScopes(HeapEntry* entry,
+ Tagged<Script> script) {
+#if V8_ENABLE_WEBASSEMBLY
+ if (script->type() == Script::Type::kWasm) return;
+#endif
+ if (!IsString(script->source())) return;
+ Tagged<String> source_str = Cast<String>(script->source());
+ if (source_str->length() == 0) return;
+
+ HandleScope handle_scope(isolate());
+ DirectHandle<Script> script_handle(script, isolate());
+
+ UnoptimizedCompileFlags flags =
+ UnoptimizedCompileFlags::ForScriptCompile(isolate(), *script_handle);
+ flags.set_allow_lazy_parsing(false);
+ flags.set_is_eager(true);
+ flags.set_is_reparse(true);
+ flags.set_allow_heap_allocation(false);
+
+ UnoptimizedCompileState compile_state;
+ ReusableUnoptimizedCompileState reusable_state(isolate());
+ ParseInfo info(isolate(), flags, &compile_state, &reusable_state);
+
+ if (parsing::ParseProgram(&info, script_handle, isolate(),
+ parsing::ReportStatisticsMode{false})) {
+ if (info.literal() != nullptr && info.literal()->scope() != nullptr) {
+ CollectScopeTree(info.literal()->scope(), 0, entry, names_, snapshot_);
+ }
+ }
+}
+
void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry,
Tagged<Script> script) {
+ // Parse the script and add its scopes to the heap snapshot.
+ ParseScriptScopes(entry, script);
+
AddIntEdge(entry, HeapGraphEdge::kInternal, "id", script->id());
AddIntEdge(entry, HeapGraphEdge::kInternal, "line_offset",
script->line_offset());
@@ -2460,12 +2605,10 @@ void V8HeapExplorer::ExtractScopeInfoReferences(HeapEntry* entry,
SetInternalReference(entry, "outer_scope_info", info->OuterScopeInfo(),
info->OuterScopeInfoOffset());
}
- if (info->HasPositionInfo()) {
- AddIntEdge(entry, HeapGraphEdge::kInternal, "start_position",
- info->StartPosition());
- AddIntEdge(entry, HeapGraphEdge::kInternal, "end_position",
- info->EndPosition());
- }
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "start_position",
+ info->StartPosition());
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "end_position",
+ info->EndPosition());
if (!info->HasInlinedLocalNames()) {
TagObject(info->context_local_names_hashtable(), "(context local names)",
HeapEntry::kCode);
@@ -3583,11 +3726,9 @@ bool NativeObjectsExplorer::IterateAndExtractReferences(
// stale native addresses for live wrapper entries.
heap_object_map_->ClearMergedNativeEntries();
- if (isolate_->heap()->cpp_heap()) {
- CppGraphBuilder::Run(
- v8::internal::CppHeap::From(isolate_->heap()->cpp_heap()), generator_,
- generator_->TakeCppHeapWrappers());
- }
+ CppGraphBuilder::Run(
+ *v8::internal::CppHeap::From(isolate_->heap()->cpp_heap()), generator_,
+ generator_->TakeCppHeapWrappers());
if (v8_flags.heap_profiler_use_embedder_graph &&
snapshot_->profiler()->HasBuildEmbedderGraphCallback()) {
@@ -3902,6 +4043,21 @@ void HeapSnapshotJSONSerializer::SerializeImpl() {
if (writer_->aborted()) return;
writer_->AddString("],\n");
+ writer_->AddString("\"scopes\":[");
+ SerializeScopes();
+ if (writer_->aborted()) return;
+ writer_->AddString("],\n");
+
+ writer_->AddString("\"scope_context_vars\":[");
+ SerializeScopeContextVars();
+ if (writer_->aborted()) return;
+ writer_->AddString("],\n");
+
+ writer_->AddString("\"scope_uses\":[");
+ SerializeScopeUses();
+ if (writer_->aborted()) return;
+ writer_->AddString("],\n");
+
writer_->AddString("\"strings\":[");
SerializeStrings();
if (writer_->aborted()) return;
@@ -4056,7 +4212,18 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() {
JSON_S("script_id") ","
JSON_S("script_object_index") ","
JSON_S("line") ","
- JSON_S("column"))
+ JSON_S("column")) ","
+ JSON_S("scope_fields") ":" JSON_A(
+ JSON_S("script_node_index") ","
+ JSON_S("scope_id") ","
+ JSON_S("depth") ","
+ JSON_S("scope_context_vars_count") ","
+ JSON_S("scope_uses_count")) ","
+ JSON_S("scope_context_var_fields") ":" JSON_A(
+ JSON_S("name")) ","
+ JSON_S("scope_use_fields") ":" JSON_A(
+ JSON_S("declaring_scope_id") ","
+ JSON_S("slot_index"))
"}");
// clang-format on
#undef JSON_S
@@ -4177,4 +4344,40 @@ void HeapSnapshotJSONSerializer::SerializeLocations() {
}
}
+void HeapSnapshotJSONSerializer::SerializeScopes() {
+ for (size_t i = 0; i < snapshot_->source_scopes().size(); ++i) {
+ if (i > 0) writer_->AddCharacter(',');
+ const auto& scope = snapshot_->source_scopes()[i];
+ writer_->AddNumber(to_node_index(scope.script_entry));
+ writer_->AddCharacter(',');
+ writer_->AddNumber(scope.scope_id);
+ writer_->AddCharacter(',');
+ writer_->AddNumber(scope.depth);
+ writer_->AddCharacter(',');
+ writer_->AddNumber(scope.scope_context_vars_count);
+ writer_->AddCharacter(',');
+ writer_->AddNumber(scope.scope_uses_count);
+ if (writer_->aborted()) return;
+ }
+}
+
+void HeapSnapshotJSONSerializer::SerializeScopeContextVars() {
+ for (size_t i = 0; i < snapshot_->source_scope_context_vars().size(); ++i) {
+ if (i > 0) writer_->AddCharacter(',');
+ writer_->AddNumber(GetStringId(snapshot_->source_scope_context_vars()[i]));
+ if (writer_->aborted()) return;
+ }
+}
+
+void HeapSnapshotJSONSerializer::SerializeScopeUses() {
+ for (size_t i = 0; i < snapshot_->source_scope_uses().size(); ++i) {
+ if (i > 0) writer_->AddCharacter(',');
+ const auto& use = snapshot_->source_scope_uses()[i];
+ writer_->AddNumber(use.declaring_scope_id);
+ writer_->AddCharacter(',');
+ writer_->AddNumber(use.slot_index);
+ if (writer_->aborted()) return;
+ }
+}
+
} // namespace v8::internal
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.h b/deps/v8/src/profiler/heap-snapshot-generator.h
index afb3175da35..d1ff451eb47 100644
--- a/deps/v8/src/profiler/heap-snapshot-generator.h
+++ b/deps/v8/src/profiler/heap-snapshot-generator.h
@@ -64,6 +64,34 @@ struct EntrySourceLocation {
const int col;
};
+// Describes one scope of the scope tree of a script. Scopes are stored in one
+// flat vector in the snapshot, in pre-order of the scope tree. The tree
+// hierarchy is encoded through the depth of each scope.
+//
+// The context variables declared by the scope and the uses of context
+// variables within the scope are stored in separate flat vectors in the
+// snapshot. Each scope owns the next scope_context_vars_count respectively
+// scope_uses_count entries of those vectors.
+struct SourceScopeInfo {
+ // The snapshot entry of the script this scope belongs to.
+ HeapEntry* script_entry;
+ // Scope id, unique within the script. Can be negative or zero.
+ int scope_id;
+ // Depth within the scope tree of the script, the root scope has depth 0.
+ int depth;
+ uint32_t scope_context_vars_count;
+ uint32_t scope_uses_count;
+};
+
+// A use of a context-allocated variable: the variable is identified by the
+// scope that declares it together with its index in that scope's context.
+// Uses are collected per scope and stored in one flat vector in the snapshot,
+// see SourceScopeInfo::scope_uses_count.
+struct SourceScopeUse {
+ int declaring_scope_id;
+ int slot_index;
+};
+
class HeapGraphEdge {
public:
enum Type {
@@ -300,6 +328,25 @@ class HeapSnapshot {
void AddScriptLineEnds(int script_id, String::LineEndsVector&& line_ends);
String::LineEndsVector& GetScriptLineEnds(int script_id);
+ void AddSourceScope(const SourceScopeInfo& info) {
+ source_scopes_.push_back(info);
+ }
+ void AddSourceScopeContextVar(const char* name) {
+ source_scope_context_vars_.push_back(name);
+ }
+ void AddSourceScopeUse(const SourceScopeUse& use) {
+ source_scope_uses_.push_back(use);
+ }
+ const std::vector<SourceScopeInfo>& source_scopes() const {
+ return source_scopes_;
+ }
+ const std::vector<const char*>& source_scope_context_vars() const {
+ return source_scope_context_vars_;
+ }
+ const std::vector<SourceScopeUse>& source_scope_uses() const {
+ return source_scope_uses_;
+ }
+
void Print(int max_depth);
private:
@@ -330,6 +377,9 @@ class HeapSnapshot {
using ScriptsLineEndsMap =
std::unordered_map<ScriptId, String::LineEndsVector>;
ScriptsLineEndsMap scripts_line_ends_map_;
+ std::vector<SourceScopeInfo> source_scopes_;
+ std::vector<const char*> source_scope_context_vars_;
+ std::vector<SourceScopeUse> source_scope_uses_;
};
@@ -526,6 +576,7 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
void ExtractSharedFunctionInfoReferences(HeapEntry* entry,
Tagged<SharedFunctionInfo> shared);
void ExtractScriptReferences(HeapEntry* entry, Tagged<Script> script);
+ void ParseScriptScopes(HeapEntry* entry, Tagged<Script> script);
void ExtractAccessorInfoReferences(HeapEntry* entry,
Tagged<AccessorInfo> accessor_info);
void ExtractAccessorPairReferences(HeapEntry* entry,
@@ -860,6 +911,9 @@ class HeapSnapshotJSONSerializer {
void SerializeStrings();
void SerializeLocation(const EntrySourceLocation& location);
void SerializeLocations();
+ void SerializeScopes();
+ void SerializeScopeContextVars();
+ void SerializeScopeUses();
static const int kEdgeFieldsCount;
static const int kNodeFieldsCountWithTraceNodeId;
diff --git a/deps/v8/src/profiler/profiler-listener.h b/deps/v8/src/profiler/profiler-listener.h
index 46d200405ba..d9b52d99902 100644
--- a/deps/v8/src/profiler/profiler-listener.h
+++ b/deps/v8/src/profiler/profiler-listener.h
@@ -71,8 +71,8 @@ class V8_EXPORT_PRIVATE ProfilerListener : public LogEventListener,
DirectHandle<SharedFunctionInfo> shared) override;
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) override;
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> sfi,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> sfi,
const char* reason) override {}
void WeakCodeClearEvent() override;
diff --git a/deps/v8/src/profiler/sampling-heap-profiler.cc b/deps/v8/src/profiler/sampling-heap-profiler.cc
index 7ea26d4064f..ea6a85243d4 100644
--- a/deps/v8/src/profiler/sampling-heap-profiler.cc
+++ b/deps/v8/src/profiler/sampling-heap-profiler.cc
@@ -41,13 +41,14 @@ intptr_t SamplingHeapProfiler::Observer::GetNextSampleInterval(uint64_t rate) {
// Samples were collected according to a poisson process. Since we have not
// recorded all allocations, we must approximate the shape of the underlying
// space of allocations based on the samples we have collected. Given that
-// we sample at rate R, the probability that an allocation of size S will be
-// sampled is 1-exp(-S/R). This function uses the above probability to
+// we sample at interval I, the probability that an allocation of size S will
+// be sampled is 1-exp(-S/I). This function uses the above probability to
// approximate the true number of allocations with size *size* given that
// *count* samples were observed.
v8::AllocationProfile::Allocation SamplingHeapProfiler::ScaleSample(
- size_t size, unsigned int count) const {
- double scale = 1.0 / (1.0 - std::exp(-static_cast<double>(size) / rate_));
+ size_t size, unsigned int count, uint64_t sample_interval) const {
+ double scale =
+ 1.0 / (1.0 - std::exp(-static_cast<double>(size) / sample_interval));
// Round count instead of truncating.
return {size, static_cast<unsigned int>(count * scale + 0.5)};
}
@@ -57,15 +58,15 @@ SamplingHeapProfiler::SamplingHeapProfiler(
v8::HeapProfiler::SamplingFlags flags)
: isolate_(Isolate::FromHeap(heap)),
heap_(heap),
- allocation_observer_(heap_, static_cast<intptr_t>(rate), rate, this,
+ allocation_observer_(heap_, static_cast<intptr_t>(rate), this,
isolate_->random_number_generator()),
names_(names),
profile_root_(nullptr, "(root)", v8::UnboundScript::kNoScriptId, 0,
next_node_id()),
stack_depth_(stack_depth),
- rate_(rate),
+ interval_(rate),
flags_(flags) {
- CHECK_GT(rate_, 0u);
+ CHECK_GT(interval_.load(std::memory_order_relaxed), 0u);
heap_->AddAllocationObserversToAllSpaces(&allocation_observer_,
&allocation_observer_);
}
@@ -94,10 +95,14 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) {
TrustedHeapLayout::InTrustedSpace(heap_object) || !IsTheHole(*obj)));
auto loc = Local<v8::Value>::FromSlot(obj.location());
+ // Record the current sampling interval so that this sample is scaled
+ // with the exact weight in effect at draw time.
+ const uint64_t interval_at_sample =
+ interval_.load(std::memory_order_relaxed);
AllocationNode* node = AddStack();
- node->allocations_[size]++;
- auto sample =
- std::make_unique<Sample>(size, node, loc, this, next_sample_id());
+ node->allocations_[{size, interval_at_sample}]++;
+ auto sample = std::make_unique<Sample>(size, node, loc, this,
+ next_sample_id(), interval_at_sample);
sample->global.SetWeak(sample.get(), OnWeakCallback,
WeakCallbackType::kParameter);
samples_.emplace(sample.get(), std::move(sample));
@@ -120,10 +125,11 @@ void SamplingHeapProfiler::OnWeakCallback(
return;
}
AllocationNode* node = sample->owner;
- DCHECK_GT(node->allocations_[sample->size], 0);
- node->allocations_[sample->size]--;
- if (node->allocations_[sample->size] == 0) {
- node->allocations_.erase(sample->size);
+ const auto key = std::make_pair(sample->size, sample->sample_interval);
+ DCHECK_GT(node->allocations_[key], 0u);
+ node->allocations_[key]--;
+ if (node->allocations_[key] == 0) {
+ node->allocations_.erase(key);
while (node->allocations_.empty() && node->children_.empty() &&
node->parent_ && !node->parent_->pinned_) {
AllocationNode* parent = node->parent_;
@@ -243,7 +249,7 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
// a GC kicks in during the tree retrieval.
node->pinned_ = true;
Local<v8::String> script_name =
- ToApiHandle<v8::String>(isolate_->factory()->InternalizeUtf8String(""));
+ ToApiHandle<v8::String>(isolate_->factory()->empty_string());
int line = v8::AllocationProfile::kNoLineNumberInfo;
int column = v8::AllocationProfile::kNoColumnNumberInfo;
std::vector<v8::AllocationProfile::Allocation> allocations;
@@ -252,10 +258,15 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
auto script_iterator = scripts.find(node->script_id_);
if (script_iterator != scripts.end()) {
DirectHandle<Script> script = script_iterator->second;
- if (IsName(script->name())) {
- Tagged<Name> name = Cast<Name>(script->name());
+ if (IsString(script->name())) {
+ script_name =
+ ToApiHandle<v8::String>(isolate_->factory()->InternalizeString(
+ direct_handle(Cast<String>(script->name()), isolate_)));
+ } else if (IsSymbol(script->name())) {
+ Tagged<Symbol> symbol = Cast<Symbol>(script->name());
script_name = ToApiHandle<v8::String>(
- isolate_->factory()->InternalizeUtf8String(names_->GetName(name)));
+ isolate_->factory()->InternalizeUtf8String(
+ names_->GetName(symbol)));
}
Script::PositionInfo pos_info;
Script::GetPositionInfo(script, node->script_position_, &pos_info);
@@ -263,8 +274,15 @@ v8::AllocationProfile::Node* SamplingHeapProfiler::TranslateAllocationNode(
column = pos_info.column + 1;
}
}
- for (auto alloc : node->allocations_) {
- allocations.push_back(ScaleSample(alloc.first, alloc.second));
+ // Entries are keyed by (size, interval). Scale each with its own interval,
+ // then merge by size for the public per-size Allocation output.
+ std::map<size_t, unsigned int> per_size;
+ for (const auto& [key, count] : node->allocations_) {
+ const auto& [size, interval] = key;
+ per_size[size] += ScaleSample(size, count, interval).count;
+ }
+ for (const auto& [size, count] : per_size) {
+ allocations.push_back({size, count});
}
profile->nodes_.push_back(v8::AllocationProfile::Node{
@@ -315,11 +333,25 @@ SamplingHeapProfiler::BuildSamples() const {
const Sample* sample = it.second.get();
const bool is_live = !sample->global.IsEmpty();
samples.emplace_back(v8::AllocationProfile::Sample{
- sample->owner->id_, sample->size, ScaleSample(sample->size, 1).count,
- sample->sample_id, is_live});
+ sample->owner->id_, sample->size,
+ ScaleSample(sample->size, 1, sample->sample_interval).count,
+ sample->sample_id, is_live, sample->sample_interval});
}
return samples;
}
+std::vector<v8::AllocationProfile::Sample> SamplingHeapProfiler::GetSamples() {
+ if (flags_ & v8::HeapProfiler::kSamplingForceGC) {
+ isolate_->heap()->CollectAllGarbage(
+ GCFlag::kNoFlags, GarbageCollectionReason::kSamplingProfiler);
+ }
+ return BuildSamples();
+}
+
+void SamplingHeapProfiler::SetSamplingInterval(uint64_t sample_interval) {
+ CHECK_GT(sample_interval, 0u);
+ interval_.store(sample_interval, std::memory_order_relaxed);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/profiler/sampling-heap-profiler.h b/deps/v8/src/profiler/sampling-heap-profiler.h
index 6a1010b9993..6a4f7d86192 100644
--- a/deps/v8/src/profiler/sampling-heap-profiler.h
+++ b/deps/v8/src/profiler/sampling-heap-profiler.h
@@ -5,10 +5,12 @@
#ifndef V8_PROFILER_SAMPLING_HEAP_PROFILER_H_
#define V8_PROFILER_SAMPLING_HEAP_PROFILER_H_
+#include <atomic>
#include <deque>
#include <map>
#include <memory>
#include <unordered_map>
+#include <vector>
#include "include/v8-profiler.h"
#include "src/heap/heap.h"
@@ -85,9 +87,12 @@ class SamplingHeapProfiler {
}
private:
+ // Keyed by (allocation size, sampling interval at draw time) so that
+ // samples drawn under different intervals are scaled with the correct
+ // weight when the tree is translated.
// TODO(alph): make use of unordered_map's here. Pay attention to
// iterator invalidation during TranslateAllocationNode.
- std::map<size_t, unsigned int> allocations_;
+ std::map<std::pair<size_t, uint64_t>, unsigned int> allocations_;
std::map<FunctionId, std::unique_ptr<AllocationNode>> children_;
AllocationNode* const parent_;
const int script_id_;
@@ -101,12 +106,14 @@ class SamplingHeapProfiler {
struct Sample {
Sample(size_t size_, AllocationNode* owner_, Local<Value> local_,
- SamplingHeapProfiler* profiler_, uint64_t sample_id)
+ SamplingHeapProfiler* profiler_, uint64_t sample_id_,
+ uint64_t sample_interval_)
: size(size_),
owner(owner_),
global(reinterpret_cast<v8::Isolate*>(profiler_->isolate_), local_),
profiler(profiler_),
- sample_id(sample_id) {}
+ sample_id(sample_id_),
+ sample_interval(sample_interval_) {}
Sample(const Sample&) = delete;
Sample& operator=(const Sample&) = delete;
const size_t size;
@@ -114,6 +121,7 @@ class SamplingHeapProfiler {
Global<Value> global;
SamplingHeapProfiler* const profiler;
const uint64_t sample_id;
+ const uint64_t sample_interval;
};
SamplingHeapProfiler(Heap* heap, StringsStorage* names, uint64_t rate,
@@ -123,19 +131,21 @@ class SamplingHeapProfiler {
SamplingHeapProfiler& operator=(const SamplingHeapProfiler&) = delete;
v8::AllocationProfile* GetAllocationProfile();
+
+ void SetSamplingInterval(uint64_t sample_interval);
+ std::vector<v8::AllocationProfile::Sample> GetSamples();
+
StringsStorage* names() const { return names_; }
private:
class Observer : public AllocationObserver {
public:
- Observer(Heap* heap, intptr_t step_size, uint64_t rate,
- SamplingHeapProfiler* profiler,
+ Observer(Heap* heap, intptr_t step_size, SamplingHeapProfiler* profiler,
base::RandomNumberGenerator* random)
: AllocationObserver(step_size),
profiler_(profiler),
heap_(heap),
- random_(random),
- rate_(rate) {}
+ random_(random) {}
protected:
void Step(int bytes_allocated, Address soon_object, size_t size) override {
@@ -148,14 +158,16 @@ class SamplingHeapProfiler {
}
}
- intptr_t GetNextStepSize() override { return GetNextSampleInterval(rate_); }
+ intptr_t GetNextStepSize() override {
+ return GetNextSampleInterval(
+ profiler_->interval_.load(std::memory_order_relaxed));
+ }
private:
intptr_t GetNextSampleInterval(uint64_t rate);
SamplingHeapProfiler* const profiler_;
Heap* const heap_;
base::RandomNumberGenerator* const random_;
- uint64_t const rate_;
};
void SampleObject(Address soon_object, size_t size);
@@ -179,8 +191,8 @@ class SamplingHeapProfiler {
v8::AllocationProfile::Node* TranslateAllocationNode(
AllocationProfile* profile, SamplingHeapProfiler::AllocationNode* node,
const std::map<int, Handle<Script>>& scripts);
- v8::AllocationProfile::Allocation ScaleSample(size_t size,
- unsigned int count) const;
+ v8::AllocationProfile::Allocation ScaleSample(size_t size, unsigned int count,
+ uint64_t sample_interval) const;
AllocationNode* AddStack();
Isolate* const isolate_;
@@ -192,7 +204,7 @@ class SamplingHeapProfiler {
AllocationNode profile_root_;
std::unordered_map<Sample*, std::unique_ptr<Sample>> samples_;
const int stack_depth_;
- const uint64_t rate_;
+ std::atomic<uint64_t> interval_;
v8::HeapProfiler::SamplingFlags flags_;
};
diff --git a/deps/v8/src/profiler/strings-storage.cc b/deps/v8/src/profiler/strings-storage.cc
index 47e90196b35..d43e039ab6e 100644
--- a/deps/v8/src/profiler/strings-storage.cc
+++ b/deps/v8/src/profiler/strings-storage.cc
@@ -6,9 +6,12 @@
#include <memory>
+#include "src/ast/ast-value-factory.h"
#include "src/base/bits.h"
+#include "src/base/small-vector.h"
#include "src/base/strings.h"
#include "src/objects/objects-inl.h"
+#include "src/strings/unicode-inl.h"
#include "src/utils/allocation.h"
namespace v8 {
@@ -45,6 +48,47 @@ const char* StringsStorage::GetCopy(const char* src) {
return reinterpret_cast<const char*>(entry->key);
}
+const char* StringsStorage::GetCopy(const AstRawString* src) {
+ if (!src || src->IsEmpty()) return "";
+
+ size_t capacity = src->length() * unibrow::Utf8::kMaxEncodedSize;
+ base::SmallVector<char, 128> utf8_buffer;
+ utf8_buffer.resize_no_init(capacity + 1);
+
+ size_t bytes_written = 0;
+ if (src->is_one_byte()) {
+ // Characters in 0x80..0xFF need to be expanded to two bytes in UTF-8.
+ bytes_written =
+ unibrow::Utf8::Encode(
+ base::Vector<const uint8_t>(src->raw_data(), src->length()),
+ utf8_buffer.data(), capacity, /*write_null=*/false,
+ /*replace_invalid_utf8=*/true)
+ .bytes_written;
+ } else {
+ bytes_written = unibrow::Utf8::Encode(
+ base::Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(src->raw_data()),
+ src->length()),
+ utf8_buffer.data(), capacity, /*write_null=*/false,
+ /*replace_invalid_utf8=*/true)
+ .bytes_written;
+ }
+ utf8_buffer[bytes_written] = '\0';
+
+ base::MutexGuard guard(&mutex_);
+ base::HashMap::Entry* entry = GetEntry(utf8_buffer.data(), bytes_written);
+ if (entry->value == nullptr) {
+ base::Vector<char> dst = base::Vector<char>::New(bytes_written + 1);
+ base::StrNCpy(dst, utf8_buffer.data(), bytes_written);
+ dst[bytes_written] = '\0';
+ entry->key = dst.begin();
+ string_size_ += bytes_written;
+ }
+ entry->value =
+ reinterpret_cast<void*>(reinterpret_cast<size_t>(entry->value) + 1);
+ return reinterpret_cast<const char*>(entry->key);
+}
+
const char* StringsStorage::GetFormatted(const char* format, ...) {
va_list args;
va_start(args, format);
diff --git a/deps/v8/src/profiler/strings-storage.h b/deps/v8/src/profiler/strings-storage.h
index 0b2aa5385bc..e00e83e1e55 100644
--- a/deps/v8/src/profiler/strings-storage.h
+++ b/deps/v8/src/profiler/strings-storage.h
@@ -16,6 +16,7 @@
namespace v8 {
namespace internal {
+class AstRawString;
class Name;
class Symbol;
@@ -32,6 +33,10 @@ class V8_EXPORT_PRIVATE StringsStorage {
// Copies the given c-string and stores it, returning the stored copy, or just
// returns the existing string in storage if it already exists.
const char* GetCopy(const char* src);
+ // Copies the given AstRawString into UTF-8 representation and stores it,
+ // returning the stored copy, or just returns the existing string in storage
+ // if it already exists.
+ const char* GetCopy(const AstRawString* src);
// Returns a formatted string, de-duplicated via the storage.
PRINTF_FORMAT(2, 3) const char* GetFormatted(const char* format, ...);
// Returns a stored string resulting from name, or "<symbol>" for a symbol.
diff --git a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
index 89cab94954a..be8451c3a16 100644
--- a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
+++ b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
@@ -6,6 +6,7 @@
#include "src/regexp/arm64/regexp-macro-assembler-arm64.h"
+#include "src/base/bits.h"
#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/logging/log.h"
@@ -546,6 +547,14 @@ void RegExpMacroAssemblerARM64::CheckNotCharacter(unsigned c,
void RegExpMacroAssemblerARM64::CheckCharacterAfterAnd(uint32_t c,
uint32_t mask,
Label* on_equal) {
+ // A single-bit mask compared against zero or itself tests one bit of the
+ // current character, which tbz/tbnz do without the And.
+ if (base::bits::IsPowerOfTwo(mask) && (c == 0 || c == mask)) {
+ TestBitAndBranchOrBacktrack(current_character(),
+ base::bits::CountTrailingZeros(mask),
+ /*jump_if_set=*/c == mask, on_equal);
+ return;
+ }
__ And(w10, current_character(), mask);
CompareAndBranchOrBacktrack(w10, c, eq, on_equal);
}
@@ -553,6 +562,13 @@ void RegExpMacroAssemblerARM64::CheckCharacterAfterAnd(uint32_t c,
void RegExpMacroAssemblerARM64::CheckNotCharacterAfterAnd(unsigned c,
unsigned mask,
Label* on_not_equal) {
+ // As in CheckCharacterAfterAnd, with the branch sense inverted.
+ if (base::bits::IsPowerOfTwo(mask) && (c == 0 || c == mask)) {
+ TestBitAndBranchOrBacktrack(current_character(),
+ base::bits::CountTrailingZeros(mask),
+ /*jump_if_set=*/c == 0, on_not_equal);
+ return;
+ }
__ And(w10, current_character(), mask);
CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
}
@@ -2258,6 +2274,20 @@ void RegExpMacroAssemblerARM64::CompareAndBranchOrBacktrack(Register reg,
__ CompareAndBranch(reg, immediate, condition, to);
}
+void RegExpMacroAssemblerARM64::TestBitAndBranchOrBacktrack(Register reg,
+ int bit,
+ bool jump_if_set,
+ Label* to) {
+ if (to == nullptr) {
+ to = &backtrack_label_;
+ }
+ if (jump_if_set) {
+ __ Tbnz(reg, bit, to);
+ } else {
+ __ Tbz(reg, bit, to);
+ }
+}
+
void RegExpMacroAssemblerARM64::CallCFunctionFromIrregexpCode(
ExternalReference function, int num_arguments) {
// Irregexp code must not set fast_c_call_caller_fp and fast_c_call_caller_pc
diff --git a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h
index f1a7460a8b3..b62d736000f 100644
--- a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h
+++ b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h
@@ -278,6 +278,11 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM64
Condition condition,
Label* to);
+ // Tests a single bit of reg and branches to the label, or backtracks if the
+ // label is nullptr. It makes use of the Tbz and Tbnz instructions.
+ void TestBitAndBranchOrBacktrack(Register reg, int bit, bool jump_if_set,
+ Label* to);
+
inline void CallIf(Label* to, Condition condition);
// Save and restore the link register on the stack in a way that
diff --git a/deps/v8/src/regexp/gen-regexp-special-case.cc b/deps/v8/src/regexp/gen-regexp-special-case.cc
index da8fa7754cd..db408405ba5 100644
--- a/deps/v8/src/regexp/gen-regexp-special-case.cc
+++ b/deps/v8/src/regexp/gen-regexp-special-case.cc
@@ -9,6 +9,8 @@
#include "src/base/strings.h"
#include "src/regexp/special-case.h"
+#include "unicode/locid.h"
+#include "unicode/unistr.h"
namespace v8 {
namespace internal {
@@ -18,6 +20,38 @@ static const base::uc32 kSurrogateStart = 0xd800;
static const base::uc32 kSurrogateEnd = 0xdfff;
static const base::uc32 kNonBmpStart = 0x10000;
+// This implements ECMAScript 2020 21.2.2.8.2 (Runtime Semantics:
+// Canonicalize) step 3, which is used to determine whether
+// characters match when ignoreCase is true and unicode is false.
+UChar32 Canonicalize(UChar32 ch) {
+ // a. Assert: ch is a UTF-16 code unit.
+ CHECK_LE(ch, 0xffff);
+
+ // b. Let s be the String value consisting of the single code unit ch.
+ icu::UnicodeString s(ch);
+
+ // c. Let u be the same result produced as if by performing the algorithm
+ // for String.prototype.toUpperCase using s as the this value.
+ // d. Assert: Type(u) is String.
+ icu::UnicodeString& u = s.toUpper(icu::Locale::getRoot());
+
+ // e. If u does not consist of a single code unit, return ch.
+ if (u.length() != 1) {
+ return ch;
+ }
+
+ // f. Let cu be u's single code unit element.
+ UChar32 cu = u.char32At(0);
+
+ // g. If the value of ch >= 128 and the value of cu < 128, return ch.
+ if (ch >= 128 && cu < 128) {
+ return ch;
+ }
+
+ // h. Return cu.
+ return cu;
+}
+
// The following code generates "src/regexp/special-case.cc".
void PrintSet(std::ofstream& out, const char* name,
const icu::UnicodeSet& set) {
@@ -63,12 +97,12 @@ void PrintSpecial(std::ofstream& out) {
continue; // Ignore surrogate range
}
current.set(i, i);
- current.closeOver(USET_CASE_INSENSITIVE);
+ current.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
// Check to see if all characters in the case-folding equivalence
// class as defined by UnicodeSet::closeOver all map to the same
// canonical value.
- UChar32 canonical = CaseFolding::Canonicalize(i);
+ UChar32 canonical = Canonicalize(i);
bool class_has_matching_canonical_char = false;
bool class_has_non_matching_canonical_char = false;
for (int32_t j = 0; j < current.getRangeCount(); j++) {
@@ -77,7 +111,7 @@ void PrintSpecial(std::ofstream& out) {
if (c == i) {
continue;
}
- UChar32 other_canonical = CaseFolding::Canonicalize(c);
+ UChar32 other_canonical = Canonicalize(c);
if (canonical == other_canonical) {
class_has_matching_canonical_char = true;
} else {
@@ -101,30 +135,29 @@ void PrintSpecial(std::ofstream& out) {
}
// Verify that no Unicode equivalence class contains two non-trivial
- // JS equivalence classes. Every character in SpecialAddSet has the
+ // JS equivalence classes. Every character in special_add has the
// same canonical value as every other non-IgnoreSet character in
// its Unicode equivalence class. Therefore, if we call closeOver on
// a set containing no IgnoreSet characters, the only characters
// that must be removed from the result are in IgnoreSet. This fact
- // is used in CharacterRange::AddCaseEquivalents.
+ // is used in CaseFolding::CloseOver.
for (int32_t i = 0; i < special_add.getRangeCount(); i++) {
for (UChar32 c = special_add.getRangeStart(i);
c <= special_add.getRangeEnd(i); c++) {
- UChar32 canonical = CaseFolding::Canonicalize(c);
+ UChar32 canonical = Canonicalize(c);
current.set(c, c);
- current.closeOver(USET_CASE_INSENSITIVE);
+ current.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
current.removeAll(ignore);
for (int32_t j = 0; j < current.getRangeCount(); j++) {
for (UChar32 c2 = current.getRangeStart(j);
c2 <= current.getRangeEnd(j); c2++) {
- CHECK_EQ(canonical, CaseFolding::Canonicalize(c2));
+ CHECK_EQ(canonical, Canonicalize(c2));
}
}
}
}
PrintSet(out, "IgnoreSet", ignore);
- PrintSet(out, "SpecialAddSet", special_add);
}
void WriteHeader(const char* header_filename) {
@@ -136,9 +169,9 @@ void WriteHeader(const char* header_filename) {
<< "// Automatically generated by regexp/gen-regexp-special-case.cc\n\n"
<< "// The following functions are used to build UnicodeSets\n"
<< "// for special cases where the case-folding algorithm used by\n"
- << "// UnicodeSet::closeOver(USET_CASE_INSENSITIVE) does not match\n"
- << "// the algorithm defined in ECMAScript 2020 21.2.2.8.2 (Runtime\n"
- << "// Semantics: Canonicalize) step 3.\n\n"
+ << "// UnicodeSet::closeOver(USET_SIMPLE_CASE_INSENSITIVE) does\n"
+ << "// not match the algorithm defined in ECMAScript 2020 21.2.2.8.2\n"
+ << "// (Runtime Semantics: Canonicalize) step 3.\n\n"
<< "#ifdef V8_INTL_SUPPORT\n"
<< "#include \"src/base/lazy-instance.h\"\n\n"
<< "#include \"src/regexp/special-case.h\"\n\n"
diff --git a/deps/v8/src/regexp/regexp-compiler-tonode.cc b/deps/v8/src/regexp/regexp-compiler-tonode.cc
index cfdfad0159b..2ae70c3fe7e 100644
--- a/deps/v8/src/regexp/regexp-compiler-tonode.cc
+++ b/deps/v8/src/regexp/regexp-compiler-tonode.cc
@@ -529,7 +529,7 @@ void CharacterRange::AddUnicodeCaseEquivalents(ZoneList<CharacterRange>* ranges,
}
// Clear the ranges list without freeing the backing store.
ranges->Rewind(0);
- set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
+ CaseFolding::CloseOver(set, CaseFolding::Mode::kUnicode);
for (int i = 0; i < set.getRangeCount(); i++) {
ranges->Add(Range(set.getRangeStart(i), set.getRangeEnd(i)), zone);
}
@@ -818,27 +818,37 @@ int CompareFirstChar(Tree* const* a, Tree* const* b) {
#ifdef V8_INTL_SUPPORT
-int CompareCaseInsensitive(const icu::UnicodeString& a,
- const icu::UnicodeString& b) {
- return a.caseCompare(b, U_FOLD_CASE_DEFAULT);
+CaseFolding::Mode CaseFoldingMode(Flags flags) {
+ return IsEitherUnicode(flags) ? CaseFolding::Mode::kUnicode
+ : CaseFolding::Mode::kNonUnicode;
}
-int CompareFirstCharCaseInsensitive(Tree* const* a, Tree* const* b) {
+// Use the matcher's case equivalence (see
+// TextNode::GetCaseIndependentLetters). Full case folding would, for example,
+// conflate U+017F and 's' under /i.
+int CompareCaseInsensitive(CaseFolding::Mode mode, base::uc16 a, base::uc16 b) {
+ if (a == b) return 0;
+ return CaseFolding::EquivalenceKey(a, mode) -
+ CaseFolding::EquivalenceKey(b, mode);
+}
+
+int CompareFirstCharCaseInsensitive(CaseFolding::Mode mode, Tree* const* a,
+ Tree* const* b) {
Atom* atom1 = FirstAtom(*a);
Atom* atom2 = FirstAtom(*b);
- return CompareCaseInsensitive(icu::UnicodeString{atom1->data().at(0)},
- icu::UnicodeString{atom2->data().at(0)});
+ return CompareCaseInsensitive(mode, atom1->data().at(0), atom2->data().at(0));
}
-bool Equals(bool ignore_case, const icu::UnicodeString& a,
- const icu::UnicodeString& b) {
+bool Equals(bool ignore_case, CaseFolding::Mode mode, base::uc16 a,
+ base::uc16 b) {
if (a == b) return true;
- if (ignore_case) return CompareCaseInsensitive(a, b) == 0;
+ if (ignore_case) return CompareCaseInsensitive(mode, a, b) == 0;
return false; // Case-sensitive equality already checked above.
}
-bool CharAtEquals(bool ignore_case, int index, const Atom* a, const Atom* b) {
- return Equals(ignore_case, a->data().at(index), b->data().at(index));
+bool CharAtEquals(bool ignore_case, CaseFolding::Mode mode, int index,
+ const Atom* a, const Atom* b) {
+ return Equals(ignore_case, mode, a->data().at(index), b->data().at(index));
}
#else
@@ -917,19 +927,19 @@ bool Disjunction::SortConsecutiveAtoms(Compiler* compiler) {
if (!StartsWithAtom(alternative)) break;
i++;
}
- // Sort atoms to get ones with common prefixes together.
- // This step is more tricky if we are in a case-independent regexp,
- // because it would change /is|I/ to /I|is/, and order matters when
- // the regexp parts don't match only disjoint starting points. To fix
- // this we have a version of CompareFirstChar that uses case-
- // independent character classes for comparison.
+ // Sort atoms to bring common prefixes together. A case-insensitive sort
+ // must preserve the order of alternatives whose first characters are
+ // equivalent: changing /is|I/ to /I|is/ would change the match result.
DCHECK_LT(first_atom, alternatives->length());
DCHECK_LE(i, alternatives->length());
DCHECK_LE(first_atom, i);
if (IsIgnoreCase(compiler->flags())) {
#ifdef V8_INTL_SUPPORT
- alternatives->StableSort(CompareFirstCharCaseInsensitive, first_atom,
- i - first_atom);
+ const CaseFolding::Mode mode = CaseFoldingMode(compiler->flags());
+ auto compare_closure = [mode](Tree* const* a, Tree* const* b) {
+ return CompareFirstCharCaseInsensitive(mode, a, b);
+ };
+ alternatives->StableSort(compare_closure, first_atom, i - first_atom);
#else
unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize =
compiler->isolate()->regexp_macro_assembler_canonicalize();
@@ -952,6 +962,9 @@ void Disjunction::RationalizeConsecutiveAtoms(Compiler* compiler) {
ZoneList<Tree*>* alternatives = this->alternatives();
int length = alternatives->length();
const bool ignore_case = IsIgnoreCase(compiler->flags());
+#ifdef V8_INTL_SUPPORT
+ const CaseFolding::Mode mode = CaseFoldingMode(compiler->flags());
+#endif // V8_INTL_SUPPORT
int write_posn = 0;
int i = 0;
@@ -965,7 +978,7 @@ void Disjunction::RationalizeConsecutiveAtoms(Compiler* compiler) {
Atom* const atom = FirstAtom(alternative);
#ifdef V8_INTL_SUPPORT
- icu::UnicodeString common_prefix(atom->data().at(0));
+ base::uc16 common_prefix = atom->data().at(0);
#else
unibrow::Mapping<unibrow::Ecma262Canonicalize>* const canonicalize =
compiler->isolate()->regexp_macro_assembler_canonicalize();
@@ -982,8 +995,8 @@ void Disjunction::RationalizeConsecutiveAtoms(Compiler* compiler) {
if (!StartsWithAtom(alternative)) break;
Atom* const alt_atom = FirstAtom(alternative);
#ifdef V8_INTL_SUPPORT
- icu::UnicodeString new_prefix(alt_atom->data().at(0));
- if (!Equals(ignore_case, new_prefix, common_prefix)) break;
+ base::uc16 new_prefix = alt_atom->data().at(0);
+ if (!Equals(ignore_case, mode, new_prefix, common_prefix)) break;
#else
unibrow::uchar new_prefix = alt_atom->data().at(0);
if (!Equals(ignore_case, canonicalize, new_prefix, common_prefix)) break;
@@ -1004,7 +1017,7 @@ void Disjunction::RationalizeConsecutiveAtoms(Compiler* compiler) {
Atom* old_atom = FirstAtom(alternatives->at(j + first_with_prefix));
for (int k = 1; k < prefix_length; k++) {
#ifdef V8_INTL_SUPPORT
- if (!CharAtEquals(ignore_case, k, alt_atom, old_atom)) {
+ if (!CharAtEquals(ignore_case, mode, k, alt_atom, old_atom)) {
#else
if (!CharAtEquals(ignore_case, canonicalize, k, alt_atom, old_atom)) {
#endif // V8_INTL_SUPPORT
@@ -1134,9 +1147,17 @@ Node* Disjunction::ToNodeImpl(Compiler* compiler, Node* on_success) {
ZoneList<Tree*>* alternatives = this->alternatives();
if (alternatives->length() > 2) {
- bool found_consecutive_atoms = SortConsecutiveAtoms(compiler);
- if (found_consecutive_atoms) RationalizeConsecutiveAtoms(compiler);
- TRACE_WITH_NODE("* After rationalizing consecutive atoms: ", this);
+ if (!compiler->read_backward() && v8_flags.regexp_optimization) {
+ // We deliberately disable SortConsecutiveAtoms and
+ // RationalizeConsecutiveAtoms in lookbehinds rather than keep
+ // rationalizing already-adjacent runs. Lookbehind disjunctions must keep
+ // source order. The code generator already turns off quick checks,
+ // Boyer-Moore and first-char dispatch when reading backward, so the
+ // passes buy almost nothing there.
+ bool found_consecutive_atoms = SortConsecutiveAtoms(compiler);
+ if (found_consecutive_atoms) RationalizeConsecutiveAtoms(compiler);
+ TRACE_WITH_NODE("* After rationalizing consecutive atoms: ", this);
+ }
FixSingleCharacterDisjunctions(compiler);
TRACE_WITH_NODE("* After fixing single character disjunctions: ", this);
if (alternatives->length() == 1) {
@@ -1738,22 +1759,8 @@ void CharacterRange::AddCaseEquivalents(Isolate* isolate, Zone* zone,
others.add(from, to);
}
- // Compute the set of additional characters that should be added,
- // using UnicodeSet::closeOver. ECMA 262 defines slightly different
- // case-folding rules than Unicode, so some characters that are
- // added by closeOver do not match anything other than themselves in
- // JS. For example, 'ſ' (U+017F LATIN SMALL LETTER LONG S) is the
- // same case-insensitive character as 's' or 'S' according to
- // Unicode, but does not match any other character in JS. To handle
- // this case, we add such characters to the IgnoreSet and filter
- // them out. We filter twice: once before calling closeOver (to
- // prevent 'ſ' from adding 's'), and once after calling closeOver
- // (to prevent 's' from adding 'ſ'). See regexp/special-case.h for
- // more information.
icu::UnicodeSet already_added(others);
- others.removeAll(CaseFolding::IgnoreSet());
- others.closeOver(USET_CASE_INSENSITIVE);
- others.removeAll(CaseFolding::IgnoreSet());
+ CaseFolding::CloseOver(others, CaseFolding::Mode::kNonUnicode);
others.removeAll(already_added);
// Add others to the ranges
diff --git a/deps/v8/src/regexp/regexp-compiler.cc b/deps/v8/src/regexp/regexp-compiler.cc
index ca1bae72c33..8d2c947bd18 100644
--- a/deps/v8/src/regexp/regexp-compiler.cc
+++ b/deps/v8/src/regexp/regexp-compiler.cc
@@ -1554,27 +1554,10 @@ int TextNode::GetCaseIndependentLetters(Compiler* compiler,
}
#ifdef V8_INTL_SUPPORT
- if (!unicode && CaseFolding::IgnoreSet().contains(character)) {
- if (one_byte_subject && character > String::kMaxOneByteCharCode) {
- // This function promises not to return a character that is impossible
- // for the subject encoding.
- return 0;
- }
- letters[0] = character;
- DCHECK(ContainsOnlyUtf16CodeUnits(letters, 1));
- return 1;
- }
- bool in_special_add_set = CaseFolding::SpecialAddSet().contains(character);
-
icu::UnicodeSet set;
set.add(character);
- set = set.closeOver(unicode ? USET_SIMPLE_CASE_INSENSITIVE
- : USET_CASE_INSENSITIVE);
-
- UChar32 canon = 0;
- if (in_special_add_set && !unicode) {
- canon = CaseFolding::Canonicalize(character);
- }
+ CaseFolding::CloseOver(set, unicode ? CaseFolding::Mode::kUnicode
+ : CaseFolding::Mode::kNonUnicode);
int32_t range_count = set.getRangeCount();
int items = 0;
@@ -1584,10 +1567,6 @@ int TextNode::GetCaseIndependentLetters(Compiler* compiler,
CHECK(end - start + items <= letter_length);
for (UChar32 cu = start; cu <= end; cu++) {
if (one_byte_subject && cu > String::kMaxOneByteCharCode) continue;
- if (!unicode && in_special_add_set &&
- CaseFolding::Canonicalize(cu) != canon) {
- continue;
- }
letters[items++] = static_cast<unibrow::uchar>(cu);
}
}
diff --git a/deps/v8/src/regexp/regexp-macro-assembler.cc b/deps/v8/src/regexp/regexp-macro-assembler.cc
index 3bdde3288ba..47d8f68735d 100644
--- a/deps/v8/src/regexp/regexp-macro-assembler.cc
+++ b/deps/v8/src/regexp/regexp-macro-assembler.cc
@@ -20,7 +20,7 @@
#ifdef V8_INTL_SUPPORT
#include "unicode/uchar.h"
-#include "unicode/unistr.h"
+#include "unicode/utf16.h"
#endif // V8_INTL_SUPPORT
namespace v8 {
@@ -72,9 +72,11 @@ int RegExpMacroAssembler::CaseInsensitiveCompareNonUnicode(Address byte_offset1,
base::uc16* substring2 = reinterpret_cast<base::uc16*>(byte_offset2);
for (size_t i = 0; i < length; i++) {
- UChar32 c1 = CaseFolding::Canonicalize(substring1[i]);
- UChar32 c2 = CaseFolding::Canonicalize(substring2[i]);
- if (c1 != c2) {
+ UChar32 c1 = substring1[i];
+ UChar32 c2 = substring2[i];
+ if (c1 == c2) continue;
+ if (CaseFolding::EquivalenceKey(c1, CaseFolding::Mode::kNonUnicode) !=
+ CaseFolding::EquivalenceKey(c2, CaseFolding::Mode::kNonUnicode)) {
return 0;
}
}
@@ -97,11 +99,25 @@ int RegExpMacroAssembler::CaseInsensitiveCompareUnicode(Address byte_offset1,
DCHECK_EQ(0, byte_length % 2);
#ifdef V8_INTL_SUPPORT
- int32_t length = static_cast<int32_t>(byte_length >> 1);
- icu::UnicodeString uni_str_1(reinterpret_cast<const char16_t*>(byte_offset1),
- length);
- return uni_str_1.caseCompare(reinterpret_cast<const char16_t*>(byte_offset2),
- length, U_FOLD_CASE_DEFAULT) == 0;
+ // Canonicalize (ECMA-262 22.2.2.9.2) applies the simple case folding of
+ // each code point separately.
+ const int32_t length = static_cast<int32_t>(byte_length >> 1);
+ const char16_t* str1 = reinterpret_cast<const char16_t*>(byte_offset1);
+ const char16_t* str2 = reinterpret_cast<const char16_t*>(byte_offset2);
+ int32_t i1 = 0;
+ int32_t i2 = 0;
+ while (i1 < length) {
+ UChar32 c1, c2;
+ U16_NEXT(str1, i1, length, c1);
+ U16_NEXT(str2, i2, length, c2);
+ if (i1 != i2) return 0;
+ if (c1 == c2) continue;
+ if (CaseFolding::EquivalenceKey(c1, CaseFolding::Mode::kUnicode) !=
+ CaseFolding::EquivalenceKey(c2, CaseFolding::Mode::kUnicode)) {
+ return 0;
+ }
+ }
+ return 1;
#else
base::uc16* substring1 = reinterpret_cast<base::uc16*>(byte_offset1);
base::uc16* substring2 = reinterpret_cast<base::uc16*>(byte_offset2);
diff --git a/deps/v8/src/regexp/special-case.h b/deps/v8/src/regexp/special-case.h
index db42d9b6bae..3279be6df31 100644
--- a/deps/v8/src/regexp/special-case.h
+++ b/deps/v8/src/regexp/special-case.h
@@ -11,13 +11,12 @@
#include "unicode/uchar.h"
#include "unicode/uniset.h"
-#include "unicode/unistr.h"
namespace v8 {
namespace internal {
namespace regexp {
-// Sets of Unicode characters that need special handling under "i" mode
+// Case equivalence for ignoreCase matching.
// For non-unicode ignoreCase matches (aka "i", not "iu"), ECMA 262
// defines slightly different case-folding rules than Unicode. An
@@ -34,81 +33,66 @@ namespace regexp {
// set of characters that should match a given input character. (See
// GetCaseIndependentLetters and CharacterRange::AddCaseEquivalents.)
// For almost all characters, this can be efficiently computed using
-// UnicodeSet::closeOver(USET_CASE_INSENSITIVE). These sets represent
-// the remaining special cases.
+// UnicodeSet::closeOver(USET_SIMPLE_CASE_INSENSITIVE). IgnoreSet represents
+// the remaining exceptions: characters that must match only themselves.
//
-// For a character c, the rules are as follows:
+// If c is in IgnoreSet, it should match only itself. For example,
+// U+00DF LATIN SMALL LETTER SHARP S uppercases to "SS", so it
+// canonicalizes to itself and must not match U+1E9E LATIN CAPITAL
+// LETTER SHARP S, even though Unicode case closure connects them.
//
-// 1. If c is in neither IgnoreSet nor SpecialAddSet, then calling
-// UnicodeSet::closeOver(USET_CASE_INSENSITIVE) on a UnicodeSet
-// containing c will produce the set of characters that should
-// match /c/i (or /[c]/i), and only those characters.
+// Otherwise, closeOver produces the correct characters after removing
+// IgnoreSet. For example, closing over 'k' adds U+212A KELVIN SIGN,
+// which is in IgnoreSet and must not match 'k' in non-unicode mode.
//
-// 2. If c is in IgnoreSet, then the only character it should match is
-// itself. However, closeOver will add additional incorrect
-// matches. For example, consider SHARP S: 'ß' (U+00DF) and 'ẞ'
-// (U+1E9E). Although closeOver('ß') = "ßẞ", uppercase('ß') is
-// "SS". Step 3.e therefore requires that 'ß' canonicalizes to
-// itself, and should not match 'ẞ'. In these cases, we can skip
-// the closeOver entirely, because it will never add an equivalent
-// character.
-//
-// 3. If c is in SpecialAddSet, then it should match at least one
-// character other than itself. However, closeOver will add at
-// least one additional incorrect match. For example, consider the
-// letter 'k'. Closing over 'k' gives "kKK" (lowercase k, uppercase
-// K, U+212A KELVIN SIGN). However, because of step 3.g, KELVIN
-// SIGN should not match either of the other two characters. As a
-// result, "k" and "K" are in SpecialAddSet (and KELVIN SIGN is in
-// IgnoreSet). To find the correct matches for characters in
-// SpecialAddSet, we closeOver the original character, but filter
-// out the results that do not have the same canonical value.
-//
-// The contents of these sets are calculated at build time by
+// The contents of IgnoreSet are calculated at build time by
// src/regexp/gen-regexp-special-case.cc, which generates
// gen/src/regexp/special-case.cc. This is done by iterating over the
// result of closeOver for each BMP character, and finding sets for
// which at least one character has a different canonical value than
// another character. Characters that match no other characters in
-// their equivalence class are added to IgnoreSet. Characters that
-// match at least one other character are added to SpecialAddSet.
+// their equivalence class are added to IgnoreSet. The generator verifies
+// that each Unicode class has at most one non-trivial JS class.
-class CaseFolding final : public AllStatic {
+class V8_EXPORT_PRIVATE CaseFolding final : public AllStatic {
public:
- static const icu::UnicodeSet& IgnoreSet();
- static const icu::UnicodeSet& SpecialAddSet();
-
- // This implements ECMAScript 2020 21.2.2.8.2 (Runtime Semantics:
- // Canonicalize) step 3, which is used to determine whether
- // characters match when ignoreCase is true and unicode is false.
- static UChar32 Canonicalize(UChar32 ch) {
- // a. Assert: ch is a UTF-16 code unit.
- CHECK_LE(ch, 0xffff);
-
- // b. Let s be the String value consisting of the single code unit ch.
- icu::UnicodeString s(ch);
-
- // c. Let u be the same result produced as if by performing the algorithm
- // for String.prototype.toUpperCase using s as the this value.
- // d. Assert: Type(u) is String.
- icu::UnicodeString& u = s.toUpper();
+ enum class Mode { kNonUnicode, kUnicode };
+
+ // Equal keys denote matching characters, but can diverge from the
+ // specification's Canonicalize operation. Non-unicode inputs are UTF-16 code
+ // units; Unicode inputs are code points.
+ static UChar32 EquivalenceKey(UChar32 c, Mode mode) {
+ DCHECK_GE(c, 0);
+ DCHECK_LE(c, mode == Mode::kNonUnicode ? 0xffff : 0x10ffff);
+ if (mode == Mode::kNonUnicode && IgnoreSet().contains(c)) return c;
+ return u_foldCase(c, U_FOLD_CASE_DEFAULT);
+ }
- // e. If u does not consist of a single code unit, return ch.
- if (u.length() != 1) {
- return ch;
+ // Close a set of characters under case equivalence, preserving its
+ // original members. Non-unicode inputs must be UTF-16 code units.
+ static void CloseOver(icu::UnicodeSet& set, Mode mode) {
+ if (mode == Mode::kUnicode) {
+ set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
+ return;
}
-
- // f. Let cu be u's single code unit element.
- UChar32 cu = u.char32At(0);
-
- // g. If the value of ch >= 128 and the value of cu < 128, return ch.
- if (ch >= 128 && cu < 128) {
- return ch;
+ if (IgnoreSet().containsNone(set)) {
+ set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
+ set.removeAll(IgnoreSet());
+ return;
}
-
- // h. Return cu.
- return cu;
+ if (IgnoreSet().containsAll(set)) return;
+ // Ignored characters neither contribute nor acquire equivalents, but
+ // must remain in the result if they were explicitly present.
+ icu::UnicodeSet ignored(set);
+ ignored.retainAll(IgnoreSet());
+ set.removeAll(IgnoreSet());
+ set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
+ set.removeAll(IgnoreSet());
+ set.addAll(ignored);
}
+
+ private:
+ static const icu::UnicodeSet& IgnoreSet();
};
} // namespace regexp
diff --git a/deps/v8/src/roots/roots-inl.h b/deps/v8/src/roots/roots-inl.h
index a98bdf426b8..fbbbe97807b 100644
--- a/deps/v8/src/roots/roots-inl.h
+++ b/deps/v8/src/roots/roots-inl.h
@@ -59,6 +59,9 @@ bool RootsTable::IsRootHandle(IndirectHandle<T> handle,
handle_at(RootIndex::k##CamelName).location()); \
}
ROOT_LIST(ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
IndirectHandle<Object> RootsTable::handle_at(RootIndex index) {
@@ -96,6 +99,9 @@ ReadOnlyRoots::ReadOnlyRoots(LocalIsolate* isolate)
return UncheckedCast<Type>(object_at(RootIndex::k##CamelName)); \
}
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
V8_RO_CONST Tagged<Boolean> ReadOnlyRoots::boolean_value(bool value) const {
diff --git a/deps/v8/src/roots/roots.cc b/deps/v8/src/roots/roots.cc
index 666c1864c82..00f2916056b 100644
--- a/deps/v8/src/roots/roots.cc
+++ b/deps/v8/src/roots/roots.cc
@@ -110,6 +110,14 @@ namespace {
READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK)
#undef ROOT_TYPE_CHECK
+
+template <typename T>
+void CheckTrustedMapHelper(RootIndex index, Tagged<T> obj) {
+ if constexpr (std::is_same_v<T, Map>) {
+ CHECK_EQ(RootsTable::IsInTrustedObjectMapList(index),
+ InstanceTypeChecker::IsTrustedObject(obj->instance_type()));
+ }
+}
} // namespace
void ReadOnlyRoots::VerifyTypes() {
@@ -118,6 +126,12 @@ void ReadOnlyRoots::VerifyTypes() {
READ_ONLY_ROOT_LIST(ROOT_TYPE_CHECK)
#undef ROOT_TYPE_CHECK
+
+#define CHECK_TRUSTED_MAP(Type, name, CamelName) \
+ CheckTrustedMapHelper(RootIndex::k##CamelName, name());
+
+ READ_ONLY_ROOT_LIST(CHECK_TRUSTED_MAP)
+#undef CHECK_TRUSTED_MAP
}
#endif // DEBUG
diff --git a/deps/v8/src/roots/roots.h b/deps/v8/src/roots/roots.h
index 73296da9753..b995b4bffd6 100644
--- a/deps/v8/src/roots/roots.h
+++ b/deps/v8/src/roots/roots.h
@@ -52,6 +52,46 @@ class RootVisitor;
EXTRA_IMPORTANT_INTERNALIZED_STRING_LIST_GENERATOR( \
INTERNALIZED_STRING_LIST_ADAPTER, V)
+// Maps for objects in trusted space that can be serialized during code caching.
+#define SERIALIZABLE_TRUSTED_OBJECT_MAP_ROOT_LIST(V) \
+ V(Map, bytecode_array_map, BytecodeArrayMap) \
+ V(Map, trusted_byte_array_map, TrustedByteArrayMap) \
+ V(Map, trusted_fixed_array_map, TrustedFixedArrayMap) \
+ V(Map, uncompiled_data_without_preparse_data_map, \
+ UncompiledDataWithoutPreparseDataMap) \
+ V(Map, uncompiled_data_with_preparse_data_map, \
+ UncompiledDataWithPreparseDataMap) \
+ V(Map, uncompiled_data_without_preparse_data_with_job_map, \
+ UncompiledDataWithoutPreparseDataWithJobMap) \
+ V(Map, uncompiled_data_with_preparse_data_and_job_map, \
+ UncompiledDataWithPreparseDataAndJobMap)
+
+// Maps for objects in trusted space
+#define TRUSTED_OBJECT_MAP_ROOT_LIST(V) \
+ V(Map, atom_regexp_data_map, AtomRegExpDataMap) \
+ V(Map, code_map, CodeMap) \
+ V(Map, debug_info_map, DebugInfoMap) \
+ V(Map, instruction_stream_map, InstructionStreamMap) \
+ V(Map, interpreter_data_map, InterpreterDataMap) \
+ V(Map, ir_regexp_data_map, IrRegExpDataMap) \
+ V(Map, protected_fixed_array_map, ProtectedFixedArrayMap) \
+ V(Map, protected_weak_fixed_array_map, ProtectedWeakFixedArrayMap) \
+ V(Map, regexp_data_map, RegExpDataMap) \
+ V(Map, shared_function_info_wrapper_map, SharedFunctionInfoWrapperMap) \
+ V(Map, trusted_foreign_map, TrustedForeignMap) \
+ V(Map, trusted_weak_fixed_array_map, TrustedWeakFixedArrayMap) \
+ IF_WASM(V, Map, wasm_capi_function_data_map, WasmCapiFunctionDataMap) \
+ IF_WASM(V, Map, wasm_dispatch_table_map, WasmDispatchTableMap) \
+ IF_WASM(V, Map, wasm_dispatch_table_for_imports_map, \
+ WasmDispatchTableForImportsMap) \
+ IF_WASM(V, Map, wasm_exported_function_data_map, \
+ WasmExportedFunctionDataMap) \
+ IF_WASM(V, Map, wasm_import_data_map, WasmImportDataMap) \
+ IF_WASM(V, Map, wasm_internal_function_map, WasmInternalFunctionMap) \
+ IF_WASM(V, Map, wasm_suspender_object_map, WasmSuspenderObjectMap) \
+ IF_WASM(V, Map, wasm_trusted_instance_data_map, WasmTrustedInstanceDataMap) \
+ SERIALIZABLE_TRUSTED_OBJECT_MAP_ROOT_LIST(V)
+
// Defines all the read-only roots in Heap.
#define STRONG_READ_ONLY_ROOT_LIST(V) \
/* Cluster the most popular ones in a few cache lines here at the top. */ \
@@ -96,6 +136,7 @@ class RootVisitor;
V(PropertyCellHole, property_cell_hole_value, PropertyCellHoleValue) \
V(StaleRegister, stale_register, StaleRegister) \
V(TerminationException, termination_exception, TerminationException) \
+ TDZ_HOLE_LIST(V) \
V(UninitializedHole, uninitialized_value, UninitializedValue) \
/* Maps */ \
V(Map, meta_map, MetaMap) \
@@ -105,11 +146,8 @@ class RootVisitor;
V(Map, two_pointer_filler_map, TwoPointerFillerMap) \
V(Map, accessor_info_map, AccessorInfoMap) \
V(Map, array_list_map, ArrayListMap) \
- V(Map, atom_regexp_data_map, AtomRegExpDataMap) \
V(Map, bigint_map, BigIntMap) \
- V(Map, bytecode_array_map, BytecodeArrayMap) \
V(Map, closure_feedback_cell_array_map, ClosureFeedbackCellArrayMap) \
- V(Map, code_map, CodeMap) \
V(Map, context_cell_map, ContextCellMap) \
V(Map, coverage_info_map, CoverageInfoMap) \
V(Map, dictionary_template_info_map, DictionaryTemplateInfoMap) \
@@ -120,9 +158,7 @@ class RootVisitor;
V(Map, hash_seed_wrapper_map, HashSeedWrapperMap) \
V(Map, function_template_info_map, FunctionTemplateInfoMap) \
V(Map, global_dictionary_map, GlobalDictionaryMap) \
- V(Map, instruction_stream_map, InstructionStreamMap) \
V(Map, interceptor_info_map, InterceptorInfoMap) \
- V(Map, ir_regexp_data_map, IrRegExpDataMap) \
V(Map, many_closures_cell_map, ManyClosuresCellMap) \
V(Map, mega_dom_handler_map, MegaDomHandlerMap) \
V(Map, module_info_map, ModuleInfoMap) \
@@ -137,7 +173,6 @@ class RootVisitor;
V(Map, ordered_hash_set_map, OrderedHashSetMap) \
V(Map, ordered_name_dictionary_map, OrderedNameDictionaryMap) \
V(Map, preparse_data_map, PreparseDataMap) \
- V(Map, regexp_data_map, RegExpDataMap) \
V(Map, regexp_match_info_map, RegExpMatchInfoMap) \
V(Map, registered_symbol_table_map, RegisteredSymbolTableMap) \
V(Map, scope_info_map, ScopeInfoMap) \
@@ -151,43 +186,17 @@ class RootVisitor;
V(Map, source_text_module_map, SourceTextModuleMap) \
V(Map, swiss_name_dictionary_map, SwissNameDictionaryMap) \
V(Map, synthetic_module_map, SyntheticModuleMap) \
- IF_WASM(V, Map, wasm_import_data_map, WasmImportDataMap) \
- IF_WASM(V, Map, wasm_capi_function_data_map, WasmCapiFunctionDataMap) \
- IF_WASM(V, Map, wasm_dispatch_table_map, WasmDispatchTableMap) \
- IF_WASM(V, Map, wasm_dispatch_table_for_imports_map, \
- WasmDispatchTableForImportsMap) \
- IF_WASM(V, Map, wasm_exported_function_data_map, \
- WasmExportedFunctionDataMap) \
- IF_WASM(V, Map, wasm_internal_function_map, WasmInternalFunctionMap) \
IF_WASM(V, Map, wasm_func_ref_map, WasmFuncRefMap) \
IF_WASM(V, Map, wasm_null_map, WasmNullMap) \
IF_WASM(V, Map, wasm_resume_data_map, WasmResumeDataMap) \
- IF_WASM(V, Map, wasm_suspender_object_map, WasmSuspenderObjectMap) \
IF_WASM(V, Map, wasm_continuation_object_map, WasmContinuationObjectMap) \
IF_WASM(V, Map, wasm_stack_object_map, WasmStackObjectMap) \
- IF_WASM(V, Map, wasm_trusted_instance_data_map, WasmTrustedInstanceDataMap) \
IF_WASM(V, Map, wasm_type_info_map, WasmTypeInfoMap) \
V(Map, weak_array_list_map, WeakArrayListMap) \
V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \
V(Map, embedder_data_array_map, EmbedderDataArrayMap) \
V(Map, weak_cell_map, WeakCellMap) \
- V(Map, trusted_fixed_array_map, TrustedFixedArrayMap) \
- V(Map, trusted_weak_fixed_array_map, TrustedWeakFixedArrayMap) \
- V(Map, trusted_byte_array_map, TrustedByteArrayMap) \
- V(Map, protected_fixed_array_map, ProtectedFixedArrayMap) \
- V(Map, protected_weak_fixed_array_map, ProtectedWeakFixedArrayMap) \
- V(Map, interpreter_data_map, InterpreterDataMap) \
- V(Map, debug_info_map, DebugInfoMap) \
- V(Map, shared_function_info_wrapper_map, SharedFunctionInfoWrapperMap) \
- V(Map, trusted_foreign_map, TrustedForeignMap) \
- V(Map, uncompiled_data_without_preparse_data_map, \
- UncompiledDataWithoutPreparseDataMap) \
- V(Map, uncompiled_data_with_preparse_data_map, \
- UncompiledDataWithPreparseDataMap) \
- V(Map, uncompiled_data_without_preparse_data_with_job_map, \
- UncompiledDataWithoutPreparseDataWithJobMap) \
- V(Map, uncompiled_data_with_preparse_data_and_job_map, \
- UncompiledDataWithPreparseDataAndJobMap) \
+ TRUSTED_OBJECT_MAP_ROOT_LIST(V) \
/* String maps */ \
V(Map, seq_two_byte_string_map, SeqTwoByteStringMap) \
V(Map, cons_two_byte_string_map, ConsTwoByteStringMap) \
@@ -544,6 +553,10 @@ enum class RootIndex : uint16_t {
kRootListLength,
+#ifndef V8_ENABLE_TDZ_HOLE
+ kTdzHoleValue = kTheHoleValue,
+#endif
+
// Helper aliases for inclusive regions of root indices.
kFirstRoot = 0,
kLastRoot = kRootListLength - 1,
@@ -573,6 +586,18 @@ enum class RootIndex : uint16_t {
kNameForProtectorCount = 0 NAME_FOR_PROTECTOR_ROOT_LIST(COUNT_ROOT),
kLastNameForProtector = kFirstNameForProtector + kNameForProtectorCount - 1,
+ kTrustedObjectMapRootsCount = 0 TRUSTED_OBJECT_MAP_ROOT_LIST(COUNT_ROOT),
+ kFirstTrustedObjectMap = kAtomRegExpDataMap,
+ kLastTrustedObjectMap =
+ kFirstTrustedObjectMap + kTrustedObjectMapRootsCount - 1,
+
+ kSerializableTrustedObjectMapRootsCount =
+ 0 SERIALIZABLE_TRUSTED_OBJECT_MAP_ROOT_LIST(COUNT_ROOT),
+ kFirstSerializableTrustedObjectMap = kBytecodeArrayMap,
+ kLastSerializableTrustedObjectMap =
+ kFirstSerializableTrustedObjectMap +
+ kSerializableTrustedObjectMapRootsCount - 1,
+
// The strong roots visited by the garbage collector (not including read-only
// roots).
kMutableRootsCount = 0
@@ -612,6 +637,24 @@ static_assert(RootIndex::kFirstNameForProtector <=
NAME_FOR_PROTECTOR_ROOT_LIST(FOR_PROTECTOR_CHECK)
#undef FOR_PROTECTOR_CHECK
+static_assert(RootIndex::kFirstTrustedObjectMap <=
+ RootIndex::kLastTrustedObjectMap);
+#define FOR_TRUSTED_MAP_CHECK(type, name, CamelName) \
+ static_assert(RootIndex::kFirstTrustedObjectMap <= RootIndex::k##CamelName); \
+ static_assert(RootIndex::k##CamelName <= RootIndex::kLastTrustedObjectMap);
+TRUSTED_OBJECT_MAP_ROOT_LIST(FOR_TRUSTED_MAP_CHECK)
+#undef FOR_TRUSTED_MAP_CHECK
+
+static_assert(RootIndex::kFirstSerializableTrustedObjectMap <=
+ RootIndex::kLastSerializableTrustedObjectMap);
+#define FOR_SERIALIZABLE_TRUSTED_MAP_CHECK(type, name, CamelName) \
+ static_assert(RootIndex::kFirstSerializableTrustedObjectMap <= \
+ RootIndex::k##CamelName); \
+ static_assert(RootIndex::k##CamelName <= \
+ RootIndex::kLastSerializableTrustedObjectMap);
+SERIALIZABLE_TRUSTED_OBJECT_MAP_ROOT_LIST(FOR_SERIALIZABLE_TRUSTED_MAP_CHECK)
+#undef FOR_SERIALIZABLE_TRUSTED_MAP_CHECK
+
#define ROOT_TYPE_FWD_DECL(Type, name, CamelName) class Type;
ROOT_LIST(ROOT_TYPE_FWD_DECL)
#undef ROOT_TYPE_FWD_DECL
@@ -637,6 +680,9 @@ class RootsTable {
#define ROOT_ACCESSOR(Type, name, CamelName) \
V8_INLINE IndirectHandle<Type> name();
ROOT_LIST(ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+ ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
V8_INLINE IndirectHandle<Object> handle_at(RootIndex root_index);
@@ -682,6 +728,21 @@ class RootsTable {
static_cast<unsigned>(RootIndex::kLastReadOnlyRoot);
}
+ static constexpr bool IsInTrustedObjectMapList(RootIndex root_index) {
+ return static_cast<unsigned>(root_index) -
+ static_cast<unsigned>(RootIndex::kFirstTrustedObjectMap) <
+ static_cast<unsigned>(RootIndex::kTrustedObjectMapRootsCount);
+ }
+
+ static constexpr bool IsInSerializableTrustedObjectMapList(
+ RootIndex root_index) {
+ return static_cast<unsigned>(root_index) -
+ static_cast<unsigned>(
+ RootIndex::kFirstSerializableTrustedObjectMap) <
+ static_cast<unsigned>(
+ RootIndex::kSerializableTrustedObjectMapRootsCount);
+ }
+
static constexpr RootIndex SingleCharacterStringIndex(int c) {
DCHECK_GE(c, 0);
DCHECK_LT(
@@ -785,6 +846,9 @@ class ReadOnlyRoots {
V8_RO_CONST V8_INLINE Tagged<Type> unchecked_##name() const;
READ_ONLY_ROOT_LIST(ROOT_ACCESSOR)
+#ifndef V8_ENABLE_TDZ_HOLE
+ ROOT_ACCESSOR(TdzHole, tdz_hole_value, TdzHoleValue)
+#endif
#undef ROOT_ACCESSOR
V8_INLINE bool IsNameForProtector(Tagged<HeapObject> object) const;
diff --git a/deps/v8/src/roots/static-roots-intl-nowasm.h b/deps/v8/src/roots/static-roots-intl-nowasm.h
index dbb438d29ab..b1c5628998c 100644
--- a/deps/v8/src/roots/static-roots-intl-nowasm.h
+++ b/deps/v8/src/roots/static-roots-intl-nowasm.h
@@ -1199,33 +1199,39 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kHashTableHoleValue = 0x4fffd;
static constexpr Tagged_t kPromiseHoleValue = 0x6fffd;
// -- End of page 1 --
- static constexpr Tagged_t kUninitializedValue = 0x8fffd;
- static constexpr Tagged_t kArgumentsMarker = 0xafffd;
+ // TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ static constexpr Tagged_t kTdzHoleValue = 0x8fffd;
+#else
+ static constexpr Tagged_t kDisabledTdzHoleValue = 0x8fffd;
+#endif
+ static constexpr Tagged_t kUninitializedValue = 0xafffd;
// -- End of page 2 --
- static constexpr Tagged_t kTerminationException = 0xcfffd;
- static constexpr Tagged_t kException = 0xefffd;
+ static constexpr Tagged_t kArgumentsMarker = 0xcfffd;
+ static constexpr Tagged_t kTerminationException = 0xefffd;
// -- End of page 3 --
- static constexpr Tagged_t kOptimizedOut = 0x10fffd;
- static constexpr Tagged_t kStaleRegister = 0x12fffd;
+ static constexpr Tagged_t kException = 0x10fffd;
+ static constexpr Tagged_t kOptimizedOut = 0x12fffd;
// -- End of page 4 --
- static constexpr Tagged_t kSelfReferenceMarker = 0x14fffd;
- static constexpr Tagged_t kBasicBlockCountersMarker = 0x16fffd;
+ static constexpr Tagged_t kStaleRegister = 0x14fffd;
+ static constexpr Tagged_t kSelfReferenceMarker = 0x16fffd;
// -- End of page 5 --
- static constexpr Tagged_t kJSMessageObjectMap = 0x180011;
- static constexpr Tagged_t kExternalMap = 0x180039;
- static constexpr Tagged_t kCppHeapExternalMap = 0x180061;
- static constexpr Tagged_t kCppGCManagedBaseMap = 0x180089;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1800b1;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1800f5;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x18011d;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x180145;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x180199;
+ static constexpr Tagged_t kBasicBlockCountersMarker = 0x18fffd;
+ static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
+ static constexpr Tagged_t kExternalMap = 0x1a0029;
+ static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
+ static constexpr Tagged_t kCppGCManagedBaseMap = 0x1a0079;
+ static constexpr Tagged_t kJSSharedArrayMap = 0x1a00a1;
+ static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00e5;
+ static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a010d;
+ static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a0135;
+ static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0189;
static constexpr Tagged_t kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x180199;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
};
-static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 1024> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1266,6 +1272,12 @@ static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kPropertyCellHoleValue,
StaticReadOnlyRoot::kStaleRegister,
StaticReadOnlyRoot::kTerminationException,
+// TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ StaticReadOnlyRoot::kTdzHoleValue,
+#else
+ StaticReadOnlyRoot::kDisabledTdzHoleValue,
+#endif
StaticReadOnlyRoot::kUninitializedValue,
StaticReadOnlyRoot::kMetaMap,
StaticReadOnlyRoot::kWeakHomomorphicFixedArrayMap,
@@ -1274,11 +1286,8 @@ static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kTwoPointerFillerMap,
StaticReadOnlyRoot::kAccessorInfoMap,
StaticReadOnlyRoot::kArrayListMap,
- StaticReadOnlyRoot::kAtomRegExpDataMap,
StaticReadOnlyRoot::kBigIntMap,
- StaticReadOnlyRoot::kBytecodeArrayMap,
StaticReadOnlyRoot::kClosureFeedbackCellArrayMap,
- StaticReadOnlyRoot::kCodeMap,
StaticReadOnlyRoot::kContextCellMap,
StaticReadOnlyRoot::kCoverageInfoMap,
StaticReadOnlyRoot::kDictionaryTemplateInfoMap,
@@ -1289,9 +1298,7 @@ static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kHashSeedWrapperMap,
StaticReadOnlyRoot::kFunctionTemplateInfoMap,
StaticReadOnlyRoot::kGlobalDictionaryMap,
- StaticReadOnlyRoot::kInstructionStreamMap,
StaticReadOnlyRoot::kInterceptorInfoMap,
- StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kManyClosuresCellMap,
StaticReadOnlyRoot::kMegaDomHandlerMap,
StaticReadOnlyRoot::kModuleInfoMap,
@@ -1306,7 +1313,6 @@ static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kOrderedHashSetMap,
StaticReadOnlyRoot::kOrderedNameDictionaryMap,
StaticReadOnlyRoot::kPreparseDataMap,
- StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kRegExpMatchInfoMap,
StaticReadOnlyRoot::kRegisteredSymbolTableMap,
StaticReadOnlyRoot::kScopeInfoMap,
@@ -1324,15 +1330,21 @@ static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kEphemeronHashTableMap,
StaticReadOnlyRoot::kEmbedderDataArrayMap,
StaticReadOnlyRoot::kWeakCellMap,
- StaticReadOnlyRoot::kTrustedFixedArrayMap,
- StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
- StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kAtomRegExpDataMap,
+ StaticReadOnlyRoot::kCodeMap,
+ StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kInstructionStreamMap,
+ StaticReadOnlyRoot::kInterpreterDataMap,
+ StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kProtectedFixedArrayMap,
StaticReadOnlyRoot::kProtectedWeakFixedArrayMap,
- StaticReadOnlyRoot::kInterpreterDataMap,
- StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kSharedFunctionInfoWrapperMap,
StaticReadOnlyRoot::kTrustedForeignMap,
+ StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
+ StaticReadOnlyRoot::kBytecodeArrayMap,
+ StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kTrustedFixedArrayMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataWithJobMap,
diff --git a/deps/v8/src/roots/static-roots-intl-wasm.h b/deps/v8/src/roots/static-roots-intl-wasm.h
index f349dc37a79..37f33f1c037 100644
--- a/deps/v8/src/roots/static-roots-intl-wasm.h
+++ b/deps/v8/src/roots/static-roots-intl-wasm.h
@@ -1225,33 +1225,40 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kHashTableHoleValue = 0x6fffd;
// -- End of page 1 --
static constexpr Tagged_t kPromiseHoleValue = 0x8fffd;
- static constexpr Tagged_t kUninitializedValue = 0xafffd;
+ // TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ static constexpr Tagged_t kTdzHoleValue = 0xafffd;
+#else
+ static constexpr Tagged_t kDisabledTdzHoleValue = 0xafffd;
+#endif
// -- End of page 2 --
- static constexpr Tagged_t kArgumentsMarker = 0xcfffd;
- static constexpr Tagged_t kTerminationException = 0xefffd;
+ static constexpr Tagged_t kUninitializedValue = 0xcfffd;
+ static constexpr Tagged_t kArgumentsMarker = 0xefffd;
// -- End of page 3 --
- static constexpr Tagged_t kException = 0x10fffd;
- static constexpr Tagged_t kOptimizedOut = 0x12fffd;
+ static constexpr Tagged_t kTerminationException = 0x10fffd;
+ static constexpr Tagged_t kException = 0x12fffd;
// -- End of page 4 --
- static constexpr Tagged_t kStaleRegister = 0x14fffd;
- static constexpr Tagged_t kSelfReferenceMarker = 0x16fffd;
+ static constexpr Tagged_t kOptimizedOut = 0x14fffd;
+ static constexpr Tagged_t kStaleRegister = 0x16fffd;
// -- End of page 5 --
- static constexpr Tagged_t kBasicBlockCountersMarker = 0x18fffd;
- static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
- static constexpr Tagged_t kExternalMap = 0x1a0029;
- static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
- static constexpr Tagged_t kCppGCManagedBaseMap = 0x1a0079;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1a00a1;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00e5;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a010d;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a0135;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0189;
+ static constexpr Tagged_t kSelfReferenceMarker = 0x18fffd;
+ static constexpr Tagged_t kBasicBlockCountersMarker = 0x1afffd;
+ // -- End of page 6 --
+ static constexpr Tagged_t kJSMessageObjectMap = 0x1c0011;
+ static constexpr Tagged_t kExternalMap = 0x1c0039;
+ static constexpr Tagged_t kCppHeapExternalMap = 0x1c0061;
+ static constexpr Tagged_t kCppGCManagedBaseMap = 0x1c0089;
+ static constexpr Tagged_t kJSSharedArrayMap = 0x1c00b1;
+ static constexpr Tagged_t kJSAtomicsMutexMap = 0x1c00f5;
+ static constexpr Tagged_t kJSAtomicsConditionMap = 0x1c011d;
+ static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1c0145;
+ static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1c0199;
static constexpr Tagged_t kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1c0199;
};
-static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 1042> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1292,6 +1299,12 @@ static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kPropertyCellHoleValue,
StaticReadOnlyRoot::kStaleRegister,
StaticReadOnlyRoot::kTerminationException,
+// TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ StaticReadOnlyRoot::kTdzHoleValue,
+#else
+ StaticReadOnlyRoot::kDisabledTdzHoleValue,
+#endif
StaticReadOnlyRoot::kUninitializedValue,
StaticReadOnlyRoot::kMetaMap,
StaticReadOnlyRoot::kWeakHomomorphicFixedArrayMap,
@@ -1300,11 +1313,8 @@ static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kTwoPointerFillerMap,
StaticReadOnlyRoot::kAccessorInfoMap,
StaticReadOnlyRoot::kArrayListMap,
- StaticReadOnlyRoot::kAtomRegExpDataMap,
StaticReadOnlyRoot::kBigIntMap,
- StaticReadOnlyRoot::kBytecodeArrayMap,
StaticReadOnlyRoot::kClosureFeedbackCellArrayMap,
- StaticReadOnlyRoot::kCodeMap,
StaticReadOnlyRoot::kContextCellMap,
StaticReadOnlyRoot::kCoverageInfoMap,
StaticReadOnlyRoot::kDictionaryTemplateInfoMap,
@@ -1315,9 +1325,7 @@ static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kHashSeedWrapperMap,
StaticReadOnlyRoot::kFunctionTemplateInfoMap,
StaticReadOnlyRoot::kGlobalDictionaryMap,
- StaticReadOnlyRoot::kInstructionStreamMap,
StaticReadOnlyRoot::kInterceptorInfoMap,
- StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kManyClosuresCellMap,
StaticReadOnlyRoot::kMegaDomHandlerMap,
StaticReadOnlyRoot::kModuleInfoMap,
@@ -1332,7 +1340,6 @@ static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kOrderedHashSetMap,
StaticReadOnlyRoot::kOrderedNameDictionaryMap,
StaticReadOnlyRoot::kPreparseDataMap,
- StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kRegExpMatchInfoMap,
StaticReadOnlyRoot::kRegisteredSymbolTableMap,
StaticReadOnlyRoot::kScopeInfoMap,
@@ -1346,33 +1353,39 @@ static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kSourceTextModuleMap,
StaticReadOnlyRoot::kSwissNameDictionaryMap,
StaticReadOnlyRoot::kSyntheticModuleMap,
- StaticReadOnlyRoot::kWasmImportDataMap,
- StaticReadOnlyRoot::kWasmCapiFunctionDataMap,
- StaticReadOnlyRoot::kWasmDispatchTableMap,
- StaticReadOnlyRoot::kWasmDispatchTableForImportsMap,
- StaticReadOnlyRoot::kWasmExportedFunctionDataMap,
- StaticReadOnlyRoot::kWasmInternalFunctionMap,
StaticReadOnlyRoot::kWasmFuncRefMap,
StaticReadOnlyRoot::kWasmNullMap,
StaticReadOnlyRoot::kWasmResumeDataMap,
- StaticReadOnlyRoot::kWasmSuspenderObjectMap,
StaticReadOnlyRoot::kWasmContinuationObjectMap,
StaticReadOnlyRoot::kWasmStackObjectMap,
- StaticReadOnlyRoot::kWasmTrustedInstanceDataMap,
StaticReadOnlyRoot::kWasmTypeInfoMap,
StaticReadOnlyRoot::kWeakArrayListMap,
StaticReadOnlyRoot::kEphemeronHashTableMap,
StaticReadOnlyRoot::kEmbedderDataArrayMap,
StaticReadOnlyRoot::kWeakCellMap,
- StaticReadOnlyRoot::kTrustedFixedArrayMap,
- StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
- StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kAtomRegExpDataMap,
+ StaticReadOnlyRoot::kCodeMap,
+ StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kInstructionStreamMap,
+ StaticReadOnlyRoot::kInterpreterDataMap,
+ StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kProtectedFixedArrayMap,
StaticReadOnlyRoot::kProtectedWeakFixedArrayMap,
- StaticReadOnlyRoot::kInterpreterDataMap,
- StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kSharedFunctionInfoWrapperMap,
StaticReadOnlyRoot::kTrustedForeignMap,
+ StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
+ StaticReadOnlyRoot::kWasmCapiFunctionDataMap,
+ StaticReadOnlyRoot::kWasmDispatchTableMap,
+ StaticReadOnlyRoot::kWasmDispatchTableForImportsMap,
+ StaticReadOnlyRoot::kWasmExportedFunctionDataMap,
+ StaticReadOnlyRoot::kWasmImportDataMap,
+ StaticReadOnlyRoot::kWasmInternalFunctionMap,
+ StaticReadOnlyRoot::kWasmSuspenderObjectMap,
+ StaticReadOnlyRoot::kWasmTrustedInstanceDataMap,
+ StaticReadOnlyRoot::kBytecodeArrayMap,
+ StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kTrustedFixedArrayMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataWithJobMap,
diff --git a/deps/v8/src/roots/static-roots-nointl-nowasm.h b/deps/v8/src/roots/static-roots-nointl-nowasm.h
index 97801275472..df5669009a4 100644
--- a/deps/v8/src/roots/static-roots-nointl-nowasm.h
+++ b/deps/v8/src/roots/static-roots-nointl-nowasm.h
@@ -1043,33 +1043,39 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kHashTableHoleValue = 0x4fffd;
static constexpr Tagged_t kPromiseHoleValue = 0x6fffd;
// -- End of page 1 --
- static constexpr Tagged_t kUninitializedValue = 0x8fffd;
- static constexpr Tagged_t kArgumentsMarker = 0xafffd;
+ // TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ static constexpr Tagged_t kTdzHoleValue = 0x8fffd;
+#else
+ static constexpr Tagged_t kDisabledTdzHoleValue = 0x8fffd;
+#endif
+ static constexpr Tagged_t kUninitializedValue = 0xafffd;
// -- End of page 2 --
- static constexpr Tagged_t kTerminationException = 0xcfffd;
- static constexpr Tagged_t kException = 0xefffd;
+ static constexpr Tagged_t kArgumentsMarker = 0xcfffd;
+ static constexpr Tagged_t kTerminationException = 0xefffd;
// -- End of page 3 --
- static constexpr Tagged_t kOptimizedOut = 0x10fffd;
- static constexpr Tagged_t kStaleRegister = 0x12fffd;
+ static constexpr Tagged_t kException = 0x10fffd;
+ static constexpr Tagged_t kOptimizedOut = 0x12fffd;
// -- End of page 4 --
- static constexpr Tagged_t kSelfReferenceMarker = 0x14fffd;
- static constexpr Tagged_t kBasicBlockCountersMarker = 0x16fffd;
+ static constexpr Tagged_t kStaleRegister = 0x14fffd;
+ static constexpr Tagged_t kSelfReferenceMarker = 0x16fffd;
// -- End of page 5 --
- static constexpr Tagged_t kJSMessageObjectMap = 0x180011;
- static constexpr Tagged_t kExternalMap = 0x180039;
- static constexpr Tagged_t kCppHeapExternalMap = 0x180061;
- static constexpr Tagged_t kCppGCManagedBaseMap = 0x180089;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1800b1;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1800f5;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x18011d;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x180145;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x180199;
+ static constexpr Tagged_t kBasicBlockCountersMarker = 0x18fffd;
+ static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
+ static constexpr Tagged_t kExternalMap = 0x1a0029;
+ static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
+ static constexpr Tagged_t kCppGCManagedBaseMap = 0x1a0079;
+ static constexpr Tagged_t kJSSharedArrayMap = 0x1a00a1;
+ static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00e5;
+ static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a010d;
+ static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a0135;
+ static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0189;
static constexpr Tagged_t kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x180199;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
};
-static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 882> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1110,6 +1116,12 @@ static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kPropertyCellHoleValue,
StaticReadOnlyRoot::kStaleRegister,
StaticReadOnlyRoot::kTerminationException,
+// TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ StaticReadOnlyRoot::kTdzHoleValue,
+#else
+ StaticReadOnlyRoot::kDisabledTdzHoleValue,
+#endif
StaticReadOnlyRoot::kUninitializedValue,
StaticReadOnlyRoot::kMetaMap,
StaticReadOnlyRoot::kWeakHomomorphicFixedArrayMap,
@@ -1118,11 +1130,8 @@ static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kTwoPointerFillerMap,
StaticReadOnlyRoot::kAccessorInfoMap,
StaticReadOnlyRoot::kArrayListMap,
- StaticReadOnlyRoot::kAtomRegExpDataMap,
StaticReadOnlyRoot::kBigIntMap,
- StaticReadOnlyRoot::kBytecodeArrayMap,
StaticReadOnlyRoot::kClosureFeedbackCellArrayMap,
- StaticReadOnlyRoot::kCodeMap,
StaticReadOnlyRoot::kContextCellMap,
StaticReadOnlyRoot::kCoverageInfoMap,
StaticReadOnlyRoot::kDictionaryTemplateInfoMap,
@@ -1133,9 +1142,7 @@ static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kHashSeedWrapperMap,
StaticReadOnlyRoot::kFunctionTemplateInfoMap,
StaticReadOnlyRoot::kGlobalDictionaryMap,
- StaticReadOnlyRoot::kInstructionStreamMap,
StaticReadOnlyRoot::kInterceptorInfoMap,
- StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kManyClosuresCellMap,
StaticReadOnlyRoot::kMegaDomHandlerMap,
StaticReadOnlyRoot::kModuleInfoMap,
@@ -1150,7 +1157,6 @@ static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kOrderedHashSetMap,
StaticReadOnlyRoot::kOrderedNameDictionaryMap,
StaticReadOnlyRoot::kPreparseDataMap,
- StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kRegExpMatchInfoMap,
StaticReadOnlyRoot::kRegisteredSymbolTableMap,
StaticReadOnlyRoot::kScopeInfoMap,
@@ -1168,15 +1174,21 @@ static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kEphemeronHashTableMap,
StaticReadOnlyRoot::kEmbedderDataArrayMap,
StaticReadOnlyRoot::kWeakCellMap,
- StaticReadOnlyRoot::kTrustedFixedArrayMap,
- StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
- StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kAtomRegExpDataMap,
+ StaticReadOnlyRoot::kCodeMap,
+ StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kInstructionStreamMap,
+ StaticReadOnlyRoot::kInterpreterDataMap,
+ StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kProtectedFixedArrayMap,
StaticReadOnlyRoot::kProtectedWeakFixedArrayMap,
- StaticReadOnlyRoot::kInterpreterDataMap,
- StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kSharedFunctionInfoWrapperMap,
StaticReadOnlyRoot::kTrustedForeignMap,
+ StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
+ StaticReadOnlyRoot::kBytecodeArrayMap,
+ StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kTrustedFixedArrayMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataWithJobMap,
diff --git a/deps/v8/src/roots/static-roots-nointl-wasm.h b/deps/v8/src/roots/static-roots-nointl-wasm.h
index a405300d56b..34609085822 100644
--- a/deps/v8/src/roots/static-roots-nointl-wasm.h
+++ b/deps/v8/src/roots/static-roots-nointl-wasm.h
@@ -1069,33 +1069,40 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kHashTableHoleValue = 0x6fffd;
// -- End of page 1 --
static constexpr Tagged_t kPromiseHoleValue = 0x8fffd;
- static constexpr Tagged_t kUninitializedValue = 0xafffd;
+ // TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ static constexpr Tagged_t kTdzHoleValue = 0xafffd;
+#else
+ static constexpr Tagged_t kDisabledTdzHoleValue = 0xafffd;
+#endif
// -- End of page 2 --
- static constexpr Tagged_t kArgumentsMarker = 0xcfffd;
- static constexpr Tagged_t kTerminationException = 0xefffd;
+ static constexpr Tagged_t kUninitializedValue = 0xcfffd;
+ static constexpr Tagged_t kArgumentsMarker = 0xefffd;
// -- End of page 3 --
- static constexpr Tagged_t kException = 0x10fffd;
- static constexpr Tagged_t kOptimizedOut = 0x12fffd;
+ static constexpr Tagged_t kTerminationException = 0x10fffd;
+ static constexpr Tagged_t kException = 0x12fffd;
// -- End of page 4 --
- static constexpr Tagged_t kStaleRegister = 0x14fffd;
- static constexpr Tagged_t kSelfReferenceMarker = 0x16fffd;
+ static constexpr Tagged_t kOptimizedOut = 0x14fffd;
+ static constexpr Tagged_t kStaleRegister = 0x16fffd;
// -- End of page 5 --
- static constexpr Tagged_t kBasicBlockCountersMarker = 0x18fffd;
- static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
- static constexpr Tagged_t kExternalMap = 0x1a0029;
- static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
- static constexpr Tagged_t kCppGCManagedBaseMap = 0x1a0079;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1a00a1;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00e5;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a010d;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a0135;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0189;
+ static constexpr Tagged_t kSelfReferenceMarker = 0x18fffd;
+ static constexpr Tagged_t kBasicBlockCountersMarker = 0x1afffd;
+ // -- End of page 6 --
+ static constexpr Tagged_t kJSMessageObjectMap = 0x1c0011;
+ static constexpr Tagged_t kExternalMap = 0x1c0039;
+ static constexpr Tagged_t kCppHeapExternalMap = 0x1c0061;
+ static constexpr Tagged_t kCppGCManagedBaseMap = 0x1c0089;
+ static constexpr Tagged_t kJSSharedArrayMap = 0x1c00b1;
+ static constexpr Tagged_t kJSAtomicsMutexMap = 0x1c00f5;
+ static constexpr Tagged_t kJSAtomicsConditionMap = 0x1c011d;
+ static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1c0145;
+ static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1c0199;
static constexpr Tagged_t kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1c0199;
};
-static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 900> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1136,6 +1143,12 @@ static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kPropertyCellHoleValue,
StaticReadOnlyRoot::kStaleRegister,
StaticReadOnlyRoot::kTerminationException,
+// TODO(leszeks): Remove DisabledTdzHole when v8_enable_tdz_hole is removed.
+#ifdef V8_ENABLE_TDZ_HOLE
+ StaticReadOnlyRoot::kTdzHoleValue,
+#else
+ StaticReadOnlyRoot::kDisabledTdzHoleValue,
+#endif
StaticReadOnlyRoot::kUninitializedValue,
StaticReadOnlyRoot::kMetaMap,
StaticReadOnlyRoot::kWeakHomomorphicFixedArrayMap,
@@ -1144,11 +1157,8 @@ static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kTwoPointerFillerMap,
StaticReadOnlyRoot::kAccessorInfoMap,
StaticReadOnlyRoot::kArrayListMap,
- StaticReadOnlyRoot::kAtomRegExpDataMap,
StaticReadOnlyRoot::kBigIntMap,
- StaticReadOnlyRoot::kBytecodeArrayMap,
StaticReadOnlyRoot::kClosureFeedbackCellArrayMap,
- StaticReadOnlyRoot::kCodeMap,
StaticReadOnlyRoot::kContextCellMap,
StaticReadOnlyRoot::kCoverageInfoMap,
StaticReadOnlyRoot::kDictionaryTemplateInfoMap,
@@ -1159,9 +1169,7 @@ static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kHashSeedWrapperMap,
StaticReadOnlyRoot::kFunctionTemplateInfoMap,
StaticReadOnlyRoot::kGlobalDictionaryMap,
- StaticReadOnlyRoot::kInstructionStreamMap,
StaticReadOnlyRoot::kInterceptorInfoMap,
- StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kManyClosuresCellMap,
StaticReadOnlyRoot::kMegaDomHandlerMap,
StaticReadOnlyRoot::kModuleInfoMap,
@@ -1176,7 +1184,6 @@ static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kOrderedHashSetMap,
StaticReadOnlyRoot::kOrderedNameDictionaryMap,
StaticReadOnlyRoot::kPreparseDataMap,
- StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kRegExpMatchInfoMap,
StaticReadOnlyRoot::kRegisteredSymbolTableMap,
StaticReadOnlyRoot::kScopeInfoMap,
@@ -1190,33 +1197,39 @@ static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kSourceTextModuleMap,
StaticReadOnlyRoot::kSwissNameDictionaryMap,
StaticReadOnlyRoot::kSyntheticModuleMap,
- StaticReadOnlyRoot::kWasmImportDataMap,
- StaticReadOnlyRoot::kWasmCapiFunctionDataMap,
- StaticReadOnlyRoot::kWasmDispatchTableMap,
- StaticReadOnlyRoot::kWasmDispatchTableForImportsMap,
- StaticReadOnlyRoot::kWasmExportedFunctionDataMap,
- StaticReadOnlyRoot::kWasmInternalFunctionMap,
StaticReadOnlyRoot::kWasmFuncRefMap,
StaticReadOnlyRoot::kWasmNullMap,
StaticReadOnlyRoot::kWasmResumeDataMap,
- StaticReadOnlyRoot::kWasmSuspenderObjectMap,
StaticReadOnlyRoot::kWasmContinuationObjectMap,
StaticReadOnlyRoot::kWasmStackObjectMap,
- StaticReadOnlyRoot::kWasmTrustedInstanceDataMap,
StaticReadOnlyRoot::kWasmTypeInfoMap,
StaticReadOnlyRoot::kWeakArrayListMap,
StaticReadOnlyRoot::kEphemeronHashTableMap,
StaticReadOnlyRoot::kEmbedderDataArrayMap,
StaticReadOnlyRoot::kWeakCellMap,
- StaticReadOnlyRoot::kTrustedFixedArrayMap,
- StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
- StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kAtomRegExpDataMap,
+ StaticReadOnlyRoot::kCodeMap,
+ StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kInstructionStreamMap,
+ StaticReadOnlyRoot::kInterpreterDataMap,
+ StaticReadOnlyRoot::kIrRegExpDataMap,
StaticReadOnlyRoot::kProtectedFixedArrayMap,
StaticReadOnlyRoot::kProtectedWeakFixedArrayMap,
- StaticReadOnlyRoot::kInterpreterDataMap,
- StaticReadOnlyRoot::kDebugInfoMap,
+ StaticReadOnlyRoot::kRegExpDataMap,
StaticReadOnlyRoot::kSharedFunctionInfoWrapperMap,
StaticReadOnlyRoot::kTrustedForeignMap,
+ StaticReadOnlyRoot::kTrustedWeakFixedArrayMap,
+ StaticReadOnlyRoot::kWasmCapiFunctionDataMap,
+ StaticReadOnlyRoot::kWasmDispatchTableMap,
+ StaticReadOnlyRoot::kWasmDispatchTableForImportsMap,
+ StaticReadOnlyRoot::kWasmExportedFunctionDataMap,
+ StaticReadOnlyRoot::kWasmImportDataMap,
+ StaticReadOnlyRoot::kWasmInternalFunctionMap,
+ StaticReadOnlyRoot::kWasmSuspenderObjectMap,
+ StaticReadOnlyRoot::kWasmTrustedInstanceDataMap,
+ StaticReadOnlyRoot::kBytecodeArrayMap,
+ StaticReadOnlyRoot::kTrustedByteArrayMap,
+ StaticReadOnlyRoot::kTrustedFixedArrayMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithPreparseDataMap,
StaticReadOnlyRoot::kUncompiledDataWithoutPreparseDataWithJobMap,
diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc
index f1accd94f3e..e3da91b8077 100644
--- a/deps/v8/src/runtime/runtime-scopes.cc
+++ b/deps/v8/src/runtime/runtime-scopes.cc
@@ -162,7 +162,7 @@ RUNTIME_FUNCTION(Runtime_DeclareModuleExports) {
Tagged<Object> value;
if (IsSmi(decl)) {
index = Smi::ToInt(decl);
- value = ReadOnlyRoots(isolate).the_hole_value();
+ value = ReadOnlyRoots(isolate).tdz_hole_value();
} else {
DirectHandle<SharedFunctionInfo> sfi(
Cast<SharedFunctionInfo>(declarations->get(i)), isolate);
@@ -838,13 +838,13 @@ MaybeDirectHandle<Object> LoadLookupSlot(
Handle<Object> receiver = isolate->factory()->undefined_value();
// Check for uninitialized bindings.
if (flag == kNeedsInitialization &&
- holder_context->IsElementTheHole(index)) {
+ holder_context->IsElementTdzHole(index)) {
THROW_NEW_ERROR(isolate,
NewReferenceError(MessageTemplate::kNotDefined, name));
}
if (receiver_return) *receiver_return = receiver;
DirectHandle<Object> value = Context::Get(holder_context, index, isolate);
- DCHECK(!IsTheHole(*value));
+ DCHECK(!IsTdzHole(*value));
return value;
}
@@ -959,7 +959,7 @@ MaybeDirectHandle<Object> StoreLookupSlot(
if (index != Context::kNotFound) {
auto holder_context = Cast<Context>(holder);
if (flag == kNeedsInitialization &&
- holder_context->IsElementTheHole(index)) {
+ holder_context->IsElementTdzHole(index)) {
THROW_NEW_ERROR(isolate,
NewReferenceError(MessageTemplate::kNotDefined, name));
}
diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc
index fac1aa757b7..9d2ef193474 100644
--- a/deps/v8/src/runtime/runtime-strings.cc
+++ b/deps/v8/src/runtime/runtime-strings.cc
@@ -6,6 +6,7 @@
#include "src/heap/heap-inl.h"
#include "src/numbers/conversions.h"
#include "src/objects/dictionary-inl.h"
+#include "src/objects/feedback-vector-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/slots.h"
@@ -213,15 +214,18 @@ Tagged<Object> StringAdd_StringConstant_Internalize(
auto feedback_vector = Cast<FeedbackVector>(maybe_feedback_vector);
- FeedbackSlot cache_slot(FeedbackVector::ToSlot(
- slot_index + kAdd_StringConstant_Internalize_CacheSlotOffset));
- DCHECK_LT(cache_slot.ToInt(), feedback_vector->length().value());
- Handle<Object> cache_obj(Cast<Object>(feedback_vector->Get(cache_slot)),
- isolate);
+ // The cache is stored in the extra slot of the feedback slot group.
+ FeedbackSlot slot(FeedbackVector::ToSlot(slot_index));
+ DCHECK_LT(
+ slot.WithOffset(kAdd_StringConstant_Internalize_CacheSlotOffset).ToInt(),
+ feedback_vector->length().value());
+
+ FeedbackNexus nexus(isolate, feedback_vector, slot);
+ Handle<Object> cache_obj(Cast<Object>(nexus.GetFeedbackExtra()), isolate);
Handle<SimpleNameDictionary> cache;
if (*cache_obj == ReadOnlyRoots{isolate}.uninitialized_symbol()) {
cache = SimpleNameDictionary::New(isolate, 1);
- feedback_vector->SynchronizedSet(cache_slot, *cache);
+ nexus.ConfigureStringAddInternalizeCache(*cache);
} else {
cache = Cast<SimpleNameDictionary>(cache_obj);
}
@@ -241,7 +245,7 @@ Tagged<Object> StringAdd_StringConstant_Internalize(
auto new_cache = SimpleNameDictionary::Set(
isolate, cache, other_operand_internalize, internalized);
if (*new_cache != *cache) {
- feedback_vector->SynchronizedSet(cache_slot, *new_cache);
+ nexus.ConfigureStringAddInternalizeCache(*new_cache);
}
return *internalized;
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc
index d0d013c6fed..9deff853cde 100644
--- a/deps/v8/src/runtime/runtime-test.cc
+++ b/deps/v8/src/runtime/runtime-test.cc
@@ -659,13 +659,12 @@ namespace {
void FinalizeOptimization(Isolate* isolate) {
DCHECK(isolate->concurrent_recompilation_enabled());
- isolate->optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
+ isolate->WaitForConcurrentOptimizationJobs();
isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions();
isolate->optimizing_compile_dispatcher()->set_finalize(true);
#if V8_ENABLE_MAGLEV
if (isolate->maglev_concurrent_dispatcher()->is_enabled()) {
- isolate->maglev_concurrent_dispatcher()->AwaitCompileJobs();
isolate->maglev_concurrent_dispatcher()->FinalizeFinishedJobs();
}
#endif // V8_ENABLE_MAGLEV
@@ -1035,14 +1034,7 @@ RUNTIME_FUNCTION(Runtime_DisableOptimizationFinalization) {
}
RUNTIME_FUNCTION(Runtime_WaitForBackgroundOptimization) {
- if (isolate->concurrent_recompilation_enabled()) {
- isolate->optimizing_compile_dispatcher()->WaitUntilCompilationJobsDone();
-#if V8_ENABLE_MAGLEV
- if (isolate->maglev_concurrent_dispatcher()->is_enabled()) {
- isolate->maglev_concurrent_dispatcher()->AwaitCompileJobs();
- }
-#endif // V8_ENABLE_MAGLEV
- }
+ isolate->WaitForConcurrentOptimizationJobs();
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1103,7 +1095,7 @@ void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
auto context = isolate->GetCurrentContext();
auto global = context->Global();
- auto target_function_name = info.Data().As<v8::String>();
+ auto target_function_name = info.DataV2().As<v8::Value>().As<v8::String>();
v8::Local<v8::Function> target;
{
Local<Value> result;
@@ -1208,6 +1200,23 @@ RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
return ReadOnlyRoots(isolate).undefined_value();
}
+RUNTIME_FUNCTION(Runtime_SetDispatchTableGCInterval) {
+ SealHandleScope shs(isolate);
+ CHECK_UNLESS_FUZZING(args.length() == 1);
+#ifdef V8_ENABLE_ALLOCATION_TIMEOUT
+ CONVERT_INT32_ARG_FUZZ_SAFE(interval, 0);
+ isolate->heap()->set_dispatch_table_gc_interval(interval);
+#else // !V8_ENABLE_ALLOCATION_TIMEOUT
+ static std::atomic_flag printed_warning = ATOMIC_FLAG_INIT;
+ if (!printed_warning.test_and_set()) {
+ base::OS::PrintError(
+ "Warning: %%SetDispatchTableGCInterval has no effect in this build. "
+ "Set the `v8_enable_test_features` GN arg to enable it.\n");
+ }
+#endif // !V8_ENABLE_ALLOCATION_TIMEOUT
+ return ReadOnlyRoots(isolate).undefined_value();
+}
+
namespace {
int FixedArrayLenFromSize(int size) {
@@ -2158,8 +2167,8 @@ RUNTIME_FUNCTION(Runtime_EnableCodeLoggingForTesting) {
DirectHandle<SharedFunctionInfo> shared) final {}
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind,
Address pc, int fp_to_sp_delta) final {}
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> shared,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> shared,
const char* reason) final {}
void WeakCodeClearEvent() final {}
diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc
index cf497cb2c54..c7a5cfee4b1 100644
--- a/deps/v8/src/runtime/runtime-wasm.cc
+++ b/deps/v8/src/runtime/runtime-wasm.cc
@@ -191,11 +191,12 @@ RUNTIME_FUNCTION(Runtime_TrapHandlerThrowWasmError) {
&wire_bytes.begin()[pos])
.first;
// shared-everything atomic instructions.
- if (op >= 0xFE4F) {
+ if (op >= 0xFE4F || op == wasm::kExprArrayWait) {
message = MessageTemplate::kWasmTrapNullDereference;
}
#define CASE(name, ...) || op == wasm::kExpr##name
- DCHECK_EQ(op >= 0xFE4F, false FOREACH_ATOMIC_GC_OPCODE(CASE));
+ DCHECK_EQ(op >= 0xFE4F || op == wasm::kExprArrayWait,
+ false FOREACH_ATOMIC_GC_OPCODE(CASE));
#undef CASE
}
return ThrowWasmError(isolate, message);
@@ -479,10 +480,7 @@ void ReplaceJSToWasmWrapper(
Tagged<JSFunction> external_function;
CHECK(func_ref->internal(isolate)->try_get_external(&external_function));
CHECK(external_function->shared()->HasWasmExportedFunctionData(isolate));
- Tagged<WasmExportedFunctionData> function_data =
- external_function->shared()->wasm_exported_function_data();
external_function->UpdateCode(isolate, wrapper_code);
- function_data->set_wrapper_code(wrapper_code);
}
} // namespace
@@ -568,46 +566,8 @@ RUNTIME_FUNCTION(Runtime_TierUpWasmToJSWrapper) {
isolate->set_context(import_data->native_context());
const wasm::CanonicalSig* sig = import_data->sig();
- DirectHandle<Object> origin(import_data->call_origin(), isolate);
wasm::WasmCodeRefScope code_ref_scope;
- if (IsWasmInternalFunction(*origin)) {
- // The tierup for `WasmInternalFunction` is special, as there may not be an
- // instance.
- int expected_arity = static_cast<int>(sig->parameter_count());
- wasm::ImportCallKind kind;
- if (IsJSFunction(import_data->callable())) {
- Tagged<SharedFunctionInfo> shared =
- Cast<JSFunction>(import_data->callable())->shared();
- expected_arity =
- shared->internal_formal_parameter_count_without_receiver();
- kind = wasm::ImportCallKind::kJSFunction;
- } else {
- kind = wasm::ImportCallKind::kUseCallBuiltin;
- }
- wasm::WasmImportWrapperCache* cache = wasm::GetWasmImportWrapperCache();
- wasm::Suspend suspend = import_data->suspend();
- std::shared_ptr<wasm::WasmWrapperHandle> wrapper_handle =
- cache->GetCompiled(isolate, {kind, sig, expected_arity, suspend});
- DCHECK_EQ(TrustedCast<WasmInternalFunction>(*origin)->call_target(),
- wrapper_handle->code_pointer());
- cache->PublishCounterUpdates(isolate);
- return ReadOnlyRoots(isolate).undefined_value();
- }
-
-#ifdef DEBUG
- int table_slot = import_data->table_slot();
- DirectHandle<WasmDispatchTable> dispatch_table;
- DirectHandle<WasmDispatchTableForImports> dispatch_table_for_imports;
- if (IsWasmDispatchTable(*origin)) {
- dispatch_table = TrustedCast<WasmDispatchTable>(origin);
- DCHECK_EQ(sig->index(), dispatch_table->sig(table_slot));
- } else {
- dispatch_table_for_imports =
- CheckedCast<WasmDispatchTableForImports>(origin);
- }
-#endif // DEBUG
-
// Compile a wrapper for the target callable.
DirectHandle<JSReceiver> callable(Cast<JSReceiver>(import_data->callable()),
isolate);
@@ -623,29 +583,16 @@ RUNTIME_FUNCTION(Runtime_TierUpWasmToJSWrapper) {
callable = resolved.callable(); // Update to ultimate target.
DCHECK_NE(wasm::ImportCallKind::kLinkError, kind);
int expected_arity = static_cast<int>(sig->parameter_count());
- if (kind == wasm::ImportCallKind ::kJSFunction) {
+ if (kind == wasm::ImportCallKind::kJSFunction) {
expected_arity = Cast<JSFunction>(callable)
->shared()
->internal_formal_parameter_count_without_receiver();
}
- // Lookup or compile a wrapper.
+ // Lookup or compile a wrapper. The returned wrapper handle is not needed
+ // because GetCompiled updates the code pointer table entry in-place.
wasm::WasmImportWrapperCache* cache = wasm::GetWasmImportWrapperCache();
- std::shared_ptr<wasm::WasmWrapperHandle> wrapper_handle =
- cache->GetCompiled(isolate, {kind, sig, expected_arity, suspend});
-
-#ifdef DEBUG
- // Check consistency of the dispatch table's target code pointer. The code
- // pointer is owned by the import wrapper cache and was updated when compiling
- // the wrapper.
- if (!dispatch_table.is_null()) {
- DCHECK_EQ(dispatch_table->target(table_slot),
- wrapper_handle->code_pointer());
- } else {
- DCHECK_EQ(dispatch_table_for_imports->target(table_slot),
- wrapper_handle->code_pointer());
- }
-#endif // DEBUG
+ cache->GetCompiled(isolate, {kind, sig, expected_arity, suspend});
cache->PublishCounterUpdates(isolate);
@@ -769,14 +716,15 @@ RUNTIME_FUNCTION(Runtime_WasmI64AtomicWait) {
timeout_ns->AsInt64());
}
-RUNTIME_FUNCTION(Runtime_WasmManagedObjectWait) {
- HandleScope scope(isolate);
- DCHECK_EQ(5, args.length());
- Tagged<HeapObject> object = Cast<HeapObject>(args[0]);
- int field_offset = args.smi_value_at(1);
- int32_t expected_value = static_cast<int32_t>(args.number_value_at(2));
- Tagged<HeapObject> waitqueue = Cast<HeapObject>(args[3]);
- Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
+namespace {
+template <typename T>
+Tagged<Object> WasmManagedObjectWait(Isolate* isolate,
+ Tagged<HeapObject> object,
+ int field_offset, T expected_value,
+ Tagged<HeapObject> waitqueue,
+ Tagged<BigInt> timeout_ns) {
+ TSAN_ACQUIRE(object.address());
+ TSAN_ACQUIRE(waitqueue.address());
if (!v8_flags.wasm_skip_null_checks &&
(object == ReadOnlyRoots(isolate).wasm_null() ||
@@ -785,16 +733,58 @@ RUNTIME_FUNCTION(Runtime_WasmManagedObjectWait) {
}
if (!HeapLayout::InAnySharedSpace(object) || !isolate->allow_atomics_wait()) {
+ const char* op_name = IsWasmStruct(object) ? "struct.wait" : "array.wait";
return ThrowWasmError(
isolate, MessageTemplate::kAtomicsOperationNotAllowed,
- {isolate->factory()->NewStringFromAsciiChecked("struct.wait")});
+ {isolate->factory()->NewStringFromAsciiChecked(op_name)});
}
- return FutexEmulation::WaitWasmManagedObject(
+ return FutexEmulation::WaitWasmManagedObject<T>(
isolate, object, field_offset,
Cast<Managed<FutexManagedObjectWaitList>>(waitqueue), expected_value,
timeout_ns->AsInt64());
}
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_WasmManagedObjectWait32) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(5, args.length());
+ Tagged<HeapObject> object = Cast<HeapObject>(args[0]);
+ int field_offset = args.smi_value_at(1);
+ int32_t expected_value = static_cast<int32_t>(args.number_value_at(2));
+ Tagged<HeapObject> waitqueue = Cast<HeapObject>(args[3]);
+ Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
+
+ return WasmManagedObjectWait<int32_t>(isolate, object, field_offset,
+ expected_value, waitqueue, timeout_ns);
+}
+
+RUNTIME_FUNCTION(Runtime_WasmManagedObjectWait64) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(5, args.length());
+ Tagged<HeapObject> object = Cast<HeapObject>(args[0]);
+ int field_offset = args.smi_value_at(1);
+ Tagged<BigInt> expected_value = Cast<BigInt>(args[2]);
+ Tagged<HeapObject> waitqueue = Cast<HeapObject>(args[3]);
+ Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
+
+ return WasmManagedObjectWait<int64_t>(isolate, object, field_offset,
+ expected_value->AsInt64(), waitqueue,
+ timeout_ns);
+}
+
+RUNTIME_FUNCTION(Runtime_WasmManagedObjectWaitRef) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(5, args.length());
+ Tagged<HeapObject> object = Cast<HeapObject>(args[0]);
+ int field_offset = args.smi_value_at(1);
+ Tagged<Object> expected_value = args[2];
+ Tagged<HeapObject> waitqueue = Cast<HeapObject>(args[3]);
+ Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
+
+ return WasmManagedObjectWait<Tagged<Object>>(
+ isolate, object, field_offset, expected_value, waitqueue, timeout_ns);
+}
RUNTIME_FUNCTION(Runtime_WasmWaitqueueNew) {
HandleScope scope(isolate);
@@ -1094,18 +1084,10 @@ RUNTIME_FUNCTION(Runtime_WasmDebugBreak) {
return ReadOnlyRoots(isolate).undefined_value();
}
-// Assumes copy ranges are in-bounds and copy length > 0.
-// TODO(manoskouk): Unify part of this with the implementation in
-// wasm-extern-refs.cc
-RUNTIME_FUNCTION(Runtime_WasmArrayCopy) {
- SealHandleScope shs(isolate);
- DisallowGarbageCollection no_gc;
- DCHECK_EQ(5, args.length());
- Tagged<WasmArray> dst_array = Cast<WasmArray>(args[0]);
- uint32_t dst_index = args.positive_smi_value_at(1);
- Tagged<WasmArray> src_array = Cast<WasmArray>(args[2]);
- uint32_t src_index = args.positive_smi_value_at(3);
- uint32_t length = args.positive_smi_value_at(4);
+namespace {
+DISABLE_TSAN Tagged<Object> WasmArrayCopyImpl(
+ Isolate* isolate, Tagged<WasmArray> dst_array, uint32_t dst_index,
+ Tagged<WasmArray> src_array, uint32_t src_index, uint32_t length) {
DCHECK_GT(length, 0);
bool overlapping_ranges =
dst_array.ptr() == src_array.ptr() &&
@@ -1135,6 +1117,23 @@ RUNTIME_FUNCTION(Runtime_WasmArrayCopy) {
}
return ReadOnlyRoots(isolate).undefined_value();
}
+} // namespace
+
+// Assumes copy ranges are in-bounds and copy length > 0.
+// TODO(manoskouk): Unify part of this with the implementation in
+// wasm-extern-refs.cc
+RUNTIME_FUNCTION(Runtime_WasmArrayCopy) {
+ SealHandleScope shs(isolate);
+ DisallowGarbageCollection no_gc;
+ DCHECK_EQ(5, args.length());
+ Tagged<WasmArray> dst_array = Cast<WasmArray>(args[0]);
+ uint32_t dst_index = args.positive_smi_value_at(1);
+ Tagged<WasmArray> src_array = Cast<WasmArray>(args[2]);
+ uint32_t src_index = args.positive_smi_value_at(3);
+ uint32_t length = args.positive_smi_value_at(4);
+ return WasmArrayCopyImpl(isolate, dst_array, dst_index, src_array, src_index,
+ length);
+}
RUNTIME_FUNCTION(Runtime_WasmAllocateDescriptorStruct) {
HandleScope scope(isolate);
@@ -1216,17 +1215,12 @@ RUNTIME_FUNCTION(Runtime_WasmArrayNewSegment) {
}
}
-RUNTIME_FUNCTION(Runtime_WasmArrayInitSegment) {
- HandleScope scope(isolate);
- DCHECK_EQ(6, args.length());
- DirectHandle<WasmTrustedInstanceData> trusted_instance_data(
- TrustedCast<WasmTrustedInstanceData>(args[0]), isolate);
- uint32_t segment_index = args.positive_smi_value_at(1);
- DirectHandle<WasmArray> array(Cast<WasmArray>(args[2]), isolate);
- uint32_t array_index = args.positive_smi_value_at(3);
- uint32_t segment_offset = args.positive_smi_value_at(4);
- uint32_t length = args.positive_smi_value_at(5);
-
+namespace {
+DISABLE_TSAN Tagged<Object> WasmArrayInitSegmentImpl(
+ Isolate* isolate,
+ DirectHandle<WasmTrustedInstanceData> trusted_instance_data,
+ uint32_t segment_index, DirectHandle<WasmArray> array, uint32_t array_index,
+ uint32_t segment_offset, uint32_t length) {
wasm::CanonicalValueType element_type =
array->map()->wasm_type_info()->element_type();
@@ -1301,6 +1295,21 @@ RUNTIME_FUNCTION(Runtime_WasmArrayInitSegment) {
return *isolate->factory()->undefined_value();
}
}
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_WasmArrayInitSegment) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(6, args.length());
+ DirectHandle<WasmTrustedInstanceData> trusted_instance_data(
+ TrustedCast<WasmTrustedInstanceData>(args[0]), isolate);
+ uint32_t segment_index = args.positive_smi_value_at(1);
+ DirectHandle<WasmArray> array(Cast<WasmArray>(args[2]), isolate);
+ uint32_t array_index = args.positive_smi_value_at(3);
+ uint32_t segment_offset = args.positive_smi_value_at(4);
+ uint32_t length = args.positive_smi_value_at(5);
+ return WasmArrayInitSegmentImpl(isolate, trusted_instance_data, segment_index,
+ array, array_index, segment_offset, length);
+}
// Allocate a new suspender, and prepare for stack switching by updating the
// active continuation, active suspender and stack limit.
@@ -2325,6 +2334,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8Array) {
uint32_t start = NumberToUint32(args[2]);
uint32_t end = NumberToUint32(args[3]);
+ TSAN_ACQUIRE(array->address());
+
MaybeDirectHandle<v8::internal::String> result_string =
isolate->factory()->NewStringFromUtf8(array, start, end, config);
if (config.variant() == unibrow::Utf8Variant::kUtf8NoTrap) {
@@ -2373,6 +2384,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16Array) {
uint32_t end = NumberToUint32(args[2]);
UnicodeConfig config(args.positive_smi_value_at(3));
+ TSAN_ACQUIRE(array->address());
+
RETURN_RESULT_OR_TRAP(
isolate->factory()->NewStringFromUtf16(array, start, end, config));
}
@@ -2395,6 +2408,8 @@ RUNTIME_FUNCTION(Runtime_WasmSubstringShared) {
uint32_t start = args.positive_smi_value_at(1);
uint32_t length = args.positive_smi_value_at(2);
+ // TSAN_ACQUIRE has been called in the Torque builtin.
+
return *isolate->factory()->NewCopiedSubstringShared(string, start, length);
}
@@ -2589,6 +2604,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringMeasureUtf8) {
HandleScope scope(isolate);
DirectHandle<String> string(Cast<String>(args[0]), isolate);
+ TSAN_ACQUIRE(string->address());
+
string = String::Flatten(isolate, string);
uint32_t length;
{
@@ -2615,6 +2632,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringMeasureWtf8) {
HandleScope scope(isolate);
DirectHandle<String> string(Cast<String>(args[0]), isolate);
+ TSAN_ACQUIRE(string->address());
+
uint32_t length = MeasureWtf8(isolate, string);
return *isolate->factory()->NewNumberFromUint(length);
}
@@ -2643,14 +2662,10 @@ RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf8) {
MessageTemplate::kWasmTrapMemOutOfBounds);
}
-RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf8Array) {
- DCHECK_EQ(4, args.length());
- HandleScope scope(isolate);
- uint32_t utf8_variant_value = args.positive_smi_value_at(0);
- DirectHandle<String> string(Cast<String>(args[1]), isolate);
- DirectHandle<WasmArray> array(Cast<WasmArray>(args[2]), isolate);
- uint32_t start = NumberToUint32(args[3]);
-
+namespace {
+DISABLE_TSAN Tagged<Object> WasmStringEncodeWtf8ArrayImpl(
+ Isolate* isolate, uint32_t utf8_variant_value, DirectHandle<String> string,
+ DirectHandle<WasmArray> array, uint32_t start) {
DCHECK(utf8_variant_value <=
static_cast<uint32_t>(unibrow::Utf8Variant::kLastUtf8Variant));
auto utf8_variant = static_cast<unibrow::Utf8Variant>(utf8_variant_value);
@@ -2661,12 +2676,28 @@ RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf8Array) {
return EncodeWtf8(isolate, utf8_variant, string, get_writable_bytes, start,
MessageTemplate::kWasmTrapArrayOutOfBounds);
}
+} // namespace
+
+RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf8Array) {
+ DCHECK_EQ(4, args.length());
+ HandleScope scope(isolate);
+ uint32_t utf8_variant_value = args.positive_smi_value_at(0);
+ DirectHandle<String> string(Cast<String>(args[1]), isolate);
+ DirectHandle<WasmArray> array(Cast<WasmArray>(args[2]), isolate);
+ uint32_t start = NumberToUint32(args[3]);
+
+ return WasmStringEncodeWtf8ArrayImpl(isolate, utf8_variant_value, string,
+ array, start);
+}
RUNTIME_FUNCTION(Runtime_WasmStringToUtf8Array) {
DCHECK_EQ(2, args.length());
HandleScope scope(isolate);
DirectHandle<String> string(Cast<String>(args[0]), isolate);
int32_t shared = args.smi_value_at(1);
+
+ TSAN_ACQUIRE(string->address());
+
uint32_t length = MeasureWtf8(isolate, string);
constexpr int kElemSize = wasm::kWasmI8.value_kind_size();
if (length > static_cast<uint32_t>(WasmArray::MaxLength(kElemSize))) {
@@ -2714,6 +2745,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf16) {
uint32_t start = args.positive_smi_value_at(4);
uint32_t length = args.positive_smi_value_at(5);
+ TSAN_ACQUIRE(string.address());
+
DCHECK(base::IsInBounds<uint32_t>(start, length, string->length()));
size_t mem_size = trusted_instance_data->memory_size(memory);
@@ -2748,6 +2781,9 @@ RUNTIME_FUNCTION(Runtime_WasmStringAsWtf8) {
DCHECK_EQ(1, args.length());
HandleScope scope(isolate);
DirectHandle<String> string(Cast<String>(args[0]), isolate);
+
+ TSAN_ACQUIRE(string->address());
+
uint32_t wtf8_length = MeasureWtf8(isolate, string);
DirectHandle<ByteArray> array = isolate->factory()->NewByteArray(wtf8_length);
@@ -2919,6 +2955,9 @@ RUNTIME_FUNCTION(Runtime_WasmStringAdd_NoMapCheck_Shared) {
DirectHandle<String> left(Cast<String>(args[0]), isolate);
DirectHandle<String> right(Cast<String>(args[1]), isolate);
+ TSAN_ACQUIRE(left->address());
+ TSAN_ACQUIRE(right->address());
+
DirectHandle<String> result;
if (isolate->factory()->WasmStringAddShared(left, right).ToHandle(&result)) {
return *result;
@@ -2985,6 +3024,21 @@ RUNTIME_FUNCTION(Runtime_WasmTypeAssertionFailed) {
// security issues in ClusterFuzz.
FATAL("[FuzzerSecurityIssueHigh] Wasm type assertion violation");
}
+
+#ifdef V8_IS_TSAN
+// Since TSAN does not know about release fences, we must manually define the
+// synchronization between object initialization and reads from that object. We
+// add a TSAN_RELEASE after the object-initialization release fence, and a
+// TSAN_ACQUIRE at the beginning of each read-only builtin (future work: also,
+// before every read of a shared object in generated code). Explainer:
+// https://docs.google.com/document/d/17RLOdAFJ2HFA4hE83wSsTYdRwHV4ZBiX_jtOUp0qatw/edit?usp=sharing
+RUNTIME_FUNCTION(Runtime_TsanAcquireForInitializationFence) {
+ DCHECK_EQ(1, args.length());
+ TSAN_ACQUIRE(Cast<HeapObject>(args[0]).address());
+ return ReadOnlyRoots(isolate).undefined_value();
+}
+#endif // V8_IS_TSAN
+
#undef RuntimeArguments
} // namespace v8::internal
diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc
index 5a5a01f0fa1..e01124b9833 100644
--- a/deps/v8/src/runtime/runtime.cc
+++ b/deps/v8/src/runtime/runtime.cc
@@ -230,6 +230,7 @@ bool Runtime::IsEnabledForFuzzing(FunctionId id) {
case Runtime::kPrepareFunctionForOptimization:
case Runtime::kPretenureAllocationSite:
case Runtime::kSetAllocationTimeout:
+ case Runtime::kSetDispatchTableGCInterval:
case Runtime::kSetForceSlowPath:
case Runtime::kSimulateNewspaceFull:
case Runtime::kWaitForBackgroundOptimization:
diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h
index 9d06fcb2f82..9c9dfa45a44 100644
--- a/deps/v8/src/runtime/runtime.h
+++ b/deps/v8/src/runtime/runtime.h
@@ -678,6 +678,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(ScheduleGCInStackCheck, 0, 1) \
F(SerializeDeserializeNow, 0, 1) \
F(SetAllocationTimeout, -1 /* 2 || 3 */, 1) \
+ F(SetDispatchTableGCInterval, 1, 1) \
F(SetBatterySaverMode, 1, 1) \
F(SetForceSlowPath, 1, 1) \
F(SetIteratorProtector, 0, 1) \
@@ -727,7 +728,9 @@ constexpr bool CanTriggerGC(T... properties) {
F(ThrowWasmStackOverflow, 0, 1) \
F(WasmI32AtomicWait, 4, 1) \
F(WasmI64AtomicWait, 5, 1) \
- F(WasmManagedObjectWait, 5, 1) \
+ F(WasmManagedObjectWait32, 5, 1) \
+ F(WasmManagedObjectWait64, 5, 1) \
+ F(WasmManagedObjectWaitRef, 5, 1) \
F(WasmWaitqueueNew, 0, 1) \
F(WasmMemoryGrow, 2, 1) \
F(WasmStackGuard, 1, 1) \
@@ -789,6 +792,8 @@ constexpr bool CanTriggerGC(T... properties) {
F(WasmConfigureAllPrototypes, 4, 1) \
F(WasmConfigureAllPrototypesOpt, 3, 1) \
F(DebugCollectWasmCoverage, 0, 1) \
+ IF_TSAN(F, TsanAcquireForInitializationFence, 1, 1, \
+ RuntimeCallProperty::kCannotTriggerGC) \
F(WasmTypeAssertionFailed, 0, 1, RuntimeCallProperty::kCannotTriggerGC)
#define FOR_EACH_INTRINSIC_WASM_TEST(F, I) \
diff --git a/deps/v8/src/sandbox/bytecode-verifier.cc b/deps/v8/src/sandbox/bytecode-verifier.cc
index 7933722bae5..059ef6707e3 100644
--- a/deps/v8/src/sandbox/bytecode-verifier.cc
+++ b/deps/v8/src/sandbox/bytecode-verifier.cc
@@ -294,6 +294,8 @@ bool BytecodeVerifier::IsAllowedRuntimeFunction(Runtime::FunctionId id) {
case Runtime::kSwissTableUpdate:
case Runtime::kSwissTableValueAt:
case Runtime::kSwissTableKeyAt:
+ case Runtime::kDebugPrintPtr:
+ case Runtime::kCopyDataPropertiesWithExcludedPropertiesOnStack:
#if V8_ENABLE_SPARKPLUG_PLUS
case Runtime::kPatchCompareOpBaselineCode:
case Runtime::kPatchCompareOpBaselineCodeAndThrow:
diff --git a/deps/v8/src/sandbox/cppheap-pointer-tag.h b/deps/v8/src/sandbox/cppheap-pointer-tag.h
new file mode 100644
index 00000000000..e24e1b6c6b6
--- /dev/null
+++ b/deps/v8/src/sandbox/cppheap-pointer-tag.h
@@ -0,0 +1,83 @@
+// Copyright 2026 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 V8_SANDBOX_CPPHEAP_POINTER_TAG_H_
+#define V8_SANDBOX_CPPHEAP_POINTER_TAG_H_
+
+#include "include/v8-sandbox.h"
+
+namespace v8::internal {
+
+// Tags for V8-internal CppHeap objects that inherit from v8::Object::Wrappable.
+#define V8_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(V) \
+ V(kTagForTesting) \
+ V(kInspectorV8ConsoleTag) \
+ V(kInspectorTaskInfoTag) \
+ V(kWasmMemoryMapDescriptorTag)
+
+// Tags for V8-internal CppHeap objects that do NOT inherit from
+// v8::Object::Wrappable.
+#define V8_NON_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(V) \
+ V(kMicrotaskQueueTag) \
+ V(kCppGCManagedTag) \
+ V(kEmbedderDataSlotTag)
+
+enum class WrappableCppHeapPointerTag : uint16_t {
+ kFirst =
+ static_cast<uint16_t>(CppHeapPointerTag::kFirstV8InternalWrappableTag),
+ // Repeat kFirst so the first macro entry gets value kFirst.
+ kBeforeFirst = kFirst - 1,
+#define DECLARE_WRAPPABLE_TAG_ENUM(name) name,
+ V8_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(DECLARE_WRAPPABLE_TAG_ENUM)
+#undef DECLARE_WRAPPABLE_TAG_ENUM
+ kLast,
+};
+
+constexpr CppHeapPointerTagRange kV8InternalWrappableTagRange(
+ CppHeapPointerTag::kFirstV8InternalWrappableTag,
+ CppHeapPointerTag::kLastV8InternalWrappableTag);
+
+constexpr CppHeapPointerTagRange kV8InternalNonWrappableTagRange(
+ CppHeapPointerTag::kFirstV8InternalNonWrappableTag,
+ CppHeapPointerTag::kLastV8InternalNonWrappableTag);
+
+static_assert(kObjectWrappableTagRange.Contains(kV8InternalWrappableTagRange));
+static_assert(kNonWrappableTagRange.Contains(kV8InternalNonWrappableTagRange));
+
+static_assert(
+ static_cast<uint16_t>(WrappableCppHeapPointerTag::kLast) - 1 <=
+ static_cast<uint16_t>(CppHeapPointerTag::kLastV8InternalWrappableTag),
+ "WrappableCppHeapPointerTag exceeds kV8InternalWrappableTagRange");
+
+#define DEFINE_WRAPPABLE_TAG_CONSTANT(name) \
+ inline constexpr CppHeapPointerTag name = \
+ static_cast<CppHeapPointerTag>(WrappableCppHeapPointerTag::name);
+V8_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(DEFINE_WRAPPABLE_TAG_CONSTANT)
+#undef DEFINE_WRAPPABLE_TAG_CONSTANT
+
+enum class NonWrappableCppHeapPointerTag : uint16_t {
+ kFirst =
+ static_cast<uint16_t>(CppHeapPointerTag::kFirstV8InternalNonWrappableTag),
+ kBeforeFirst = kFirst - 1,
+#define DECLARE_NON_WRAPPABLE_TAG_ENUM(name) name,
+ V8_NON_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(DECLARE_NON_WRAPPABLE_TAG_ENUM)
+#undef DECLARE_NON_WRAPPABLE_TAG_ENUM
+ kLast,
+};
+
+static_assert(
+ static_cast<uint16_t>(NonWrappableCppHeapPointerTag::kLast) - 1 <=
+ static_cast<uint16_t>(
+ CppHeapPointerTag::kLastV8InternalNonWrappableTag),
+ "NonWrappableCppHeapPointerTag exceeds kV8InternalNonWrappableTagRange");
+
+#define DEFINE_NON_WRAPPABLE_TAG_CONSTANT(name) \
+ inline constexpr CppHeapPointerTag name = \
+ static_cast<CppHeapPointerTag>(NonWrappableCppHeapPointerTag::name);
+V8_NON_WRAPPABLE_CPP_HEAP_POINTER_TAGS_LIST(DEFINE_NON_WRAPPABLE_TAG_CONSTANT)
+#undef DEFINE_NON_WRAPPABLE_TAG_CONSTANT
+
+} // namespace v8::internal
+
+#endif // V8_SANDBOX_CPPHEAP_POINTER_TAG_H_
diff --git a/deps/v8/src/sandbox/cppheap-pointer.h b/deps/v8/src/sandbox/cppheap-pointer.h
index 0e9a993d454..2026cd8a16f 100644
--- a/deps/v8/src/sandbox/cppheap-pointer.h
+++ b/deps/v8/src/sandbox/cppheap-pointer.h
@@ -7,6 +7,7 @@
#include "include/v8-sandbox.h"
#include "src/common/globals.h"
+#include "src/sandbox/cppheap-pointer-tag.h"
#include "src/sandbox/isolate.h"
namespace v8::internal {
diff --git a/deps/v8/src/sandbox/external-pointer-inl.h b/deps/v8/src/sandbox/external-pointer-inl.h
index 31b272cb55c..37aa59d2186 100644
--- a/deps/v8/src/sandbox/external-pointer-inl.h
+++ b/deps/v8/src/sandbox/external-pointer-inl.h
@@ -152,10 +152,9 @@ inline Address ExternalPointerMember<kTagRange>::RedirectValue(
}
template <ExternalPointerTag tag>
-V8_INLINE void InitExternalPointerField(Address host_address,
- Address field_address,
- IsolateForSandbox isolate,
- Address value) {
+V8_INLINE ExternalPointerHandle
+InitExternalPointerField(Address host_address, Address field_address,
+ IsolateForSandbox isolate, Address value) {
#ifdef V8_ENABLE_SANDBOX
static_assert(tag != kExternalPointerNullTag);
ExternalPointerTable& table = isolate.GetExternalPointerTableFor(tag);
@@ -166,15 +165,16 @@ V8_INLINE void InitExternalPointerField(Address host_address,
// threads may access an uninitialized table entry and crash.
auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
base::AsAtomic32::Release_Store(location, handle);
+ return handle;
#else
WriteExternalPointerField<tag>(field_address, isolate, value);
+ return kNullExternalPointerHandle;
#endif // V8_ENABLE_SANDBOX
}
-V8_INLINE void InitExternalPointerField(Address host_address,
- Address field_address,
- IsolateForSandbox isolate,
- ExternalPointerTag tag, Address value) {
+V8_INLINE ExternalPointerHandle InitExternalPointerField(
+ Address host_address, Address field_address, IsolateForSandbox isolate,
+ ExternalPointerTag tag, Address value) {
#ifdef V8_ENABLE_SANDBOX
DCHECK_NE(tag, kExternalPointerNullTag);
ExternalPointerTable& table = isolate.GetExternalPointerTableFor(tag);
@@ -185,8 +185,10 @@ V8_INLINE void InitExternalPointerField(Address host_address,
// threads may access an uninitialized table entry and crash.
auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
base::AsAtomic32::Release_Store(location, handle);
+ return handle;
#else
WriteExternalPointerField(field_address, isolate, tag, value);
+ return kNullExternalPointerHandle;
#endif // V8_ENABLE_SANDBOX
}
diff --git a/deps/v8/src/sandbox/external-pointer.h b/deps/v8/src/sandbox/external-pointer.h
index 3240816823c..7037df266f0 100644
--- a/deps/v8/src/sandbox/external-pointer.h
+++ b/deps/v8/src/sandbox/external-pointer.h
@@ -139,14 +139,12 @@ V8_INLINE void InitLazyExternalPointerField(Address field_address);
// Creates and initializes an entry in the external pointer table and writes the
// handle for that entry to the field.
template <ExternalPointerTag tag>
-V8_INLINE void InitExternalPointerField(Address host_address,
- Address field_address,
- IsolateForSandbox isolate,
- Address value);
-V8_INLINE void InitExternalPointerField(Address host_address,
- Address field_address,
- IsolateForSandbox isolate,
- ExternalPointerTag tag, Address value);
+V8_INLINE ExternalPointerHandle
+InitExternalPointerField(Address host_address, Address field_address,
+ IsolateForSandbox isolate, Address value);
+V8_INLINE ExternalPointerHandle InitExternalPointerField(
+ Address host_address, Address field_address, IsolateForSandbox isolate,
+ ExternalPointerTag tag, Address value);
// If the sandbox is enabled: reads the ExternalPointerHandle from the field and
// loads the corresponding external pointer from the external pointer table. If
diff --git a/deps/v8/src/sandbox/generated-code-validator-arm64.cc b/deps/v8/src/sandbox/generated-code-validator-arm64.cc
index 9a5ed461a80..ad4694d3b29 100644
--- a/deps/v8/src/sandbox/generated-code-validator-arm64.cc
+++ b/deps/v8/src/sandbox/generated-code-validator-arm64.cc
@@ -349,11 +349,20 @@ class InstructionChecker {
}
}
- // Verifies that system register instruction MSR is never used. This prevents
+ // Verifies that system registers are never updated. This prevents
// unintended modification of CPU control flags or floating-point execution
// state.
void CheckNoSystemRegisterWrites(const uint8_t* pc, const Da64Inst& instr) {
- VALIDATOR_CHECK(instr.mnem != DA64I_MSR,
+ static constexpr Da64InstKind prohibited_instructions[] = {
+ DA64I_SYS, DA64I_SYSL, DA64I_MSR,
+ DA64I_MSR_UAO, DA64I_MSR_PAN, DA64I_MSR_SPSel,
+ DA64I_MSR_ALLINT, DA64I_MSR_PM, DA64I_MSR_SSBS,
+ DA64I_MSR_DIT, DA64I_MSR_TCO, DA64I_MSR_DAIFSet,
+ DA64I_MSR_DAIFClr, DA64I_MSR_SVCRSM, DA64I_MSR_SVCRZA,
+ DA64I_MSR_SVCRSMZA};
+ VALIDATOR_CHECK(std::find(std::begin(prohibited_instructions),
+ std::end(prohibited_instructions),
+ instr.mnem) == std::end(prohibited_instructions),
"Instruction writes to prohibited system registers");
}
diff --git a/deps/v8/src/sandbox/indirect-pointer-tag.h b/deps/v8/src/sandbox/indirect-pointer-tag.h
index 454c5e8d382..725bc2fa966 100644
--- a/deps/v8/src/sandbox/indirect-pointer-tag.h
+++ b/deps/v8/src/sandbox/indirect-pointer-tag.h
@@ -56,17 +56,20 @@ enum IndirectPointerTag : uint16_t {
kWasmTrustedInstanceDataIndirectPointerTag = 4,
kWasmDispatchTableIndirectPointerTag,
kWasmSuspenderIndirectPointerTag,
- kWasmExportedFunctionDataIndirectPointerTag,
- kWasmCapiFunctionDataIndirectPointerTag,
kRegExpDataIndirectPointerTag,
+ kDebugInfoIndirectPointerTag,
+
+ kFirstSFITrustedDataTag = kDebugInfoIndirectPointerTag + 1,
+ kWasmExportedFunctionDataIndirectPointerTag = kFirstSFITrustedDataTag,
+ kWasmCapiFunctionDataIndirectPointerTag,
kInterpreterDataIndirectPointerTag,
kUncompiledDataIndirectPointerTag,
- kDebugInfoIndirectPointerTag,
kBytecodeArrayIndirectPointerTag,
// All code pointers share the same tag (pointing to Code objects). Their
// instruction stream start is guarded by another tag (CodeEntrypointTag).
kCodeIndirectPointerTag,
- kLastPerIsolateTrustedPointerTag = kCodeIndirectPointerTag,
+ kLastSFITrustedDataTag = kCodeIndirectPointerTag,
+ kLastPerIsolateTrustedPointerTag = kLastSFITrustedDataTag,
// The maximum tag in kAllIndirectPointerTags. Padded to a (pow2-1) to enable
// fast, single-instruction bitwise untagging (see
@@ -174,6 +177,9 @@ constexpr IndirectPointerTagRange kWasmFunctionDataIndirectPointerTagRange(
kWasmExportedFunctionDataIndirectPointerTag,
kWasmCapiFunctionDataIndirectPointerTag);
+constexpr IndirectPointerTagRange kSFITrustedDataIndirectPointerRange(
+ kFirstSFITrustedDataTag, kLastSFITrustedDataTag);
+
// The kAllIndirectPointerTags contains all regular tags including the code tag.
static_assert(kAllIndirectPointerTags.Contains(kAllSharedIndirectPointerTags));
static_assert(
diff --git a/deps/v8/src/sandbox/js-dispatch-table-inl.h b/deps/v8/src/sandbox/js-dispatch-table-inl.h
index 5c2dd9a2d8e..5566fc682a0 100644
--- a/deps/v8/src/sandbox/js-dispatch-table-inl.h
+++ b/deps/v8/src/sandbox/js-dispatch-table-inl.h
@@ -29,7 +29,6 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
bool mark_as_alive) {
DCHECK_NE(entrypoint, kNullAddress);
DCHECK_EQ(object & kHeapObjectTag, 0);
-#if !defined(__illumos__) || !defined(V8_TARGET_ARCH_64_BIT)
DCHECK_EQ((((object - kObjectPointerOffset) << kObjectPointerShift) >>
kObjectPointerShift) +
kObjectPointerOffset,
@@ -37,7 +36,6 @@ void JSDispatchEntry::MakeJSDispatchEntry(Address object, Address entrypoint,
DCHECK_EQ((object - kObjectPointerOffset) + kObjectPointerOffset, object);
DCHECK_LT((object - kObjectPointerOffset),
1ULL << ((sizeof(encoded_word_) * 8) - kObjectPointerShift));
-#endif /* __illumos__ & 64-bit */
Address payload = ((object - kObjectPointerOffset) << kObjectPointerShift) |
(parameter_count & kParameterCountMask);
@@ -63,16 +61,8 @@ Address JSDispatchEntry::GetCodePointer() const {
// and so may be 0 or 1 here. As the return value is a tagged pointer, the
// bit must be 1 when returned, so we need to set it here.
Address payload = encoded_word_.load(std::memory_order_acquire);
-#if defined(__illumos__) && defined(V8_TARGET_ARCH_64_BIT)
- // Unsigned types won't sign-extend on shift-right, but we need to do
- // this with illumos VA48 addressing.
- DCHECK_EQ(kObjectPointerOffset, 0);
- return (Address)((intptr_t)payload >> (int)kObjectPointerShift) |
- kHeapObjectTag;
-#else
return ((payload >> kObjectPointerShift) + kObjectPointerOffset) |
kHeapObjectTag;
-#endif /* __illumos__ & 64-bit */
}
Tagged<Code> JSDispatchEntry::GetCode() const {
@@ -279,12 +269,7 @@ void JSDispatchEntry::MakeFreelistEntry(uint32_t next_entry_index) {
#ifdef V8_TARGET_ARCH_64_BIT
bool JSDispatchEntry::IsFreelistEntry(Address entrypoint) const {
-#ifdef __illumos__
- // See the illumos definition of kFreeEntryTag for why we have to do this.
- return (entrypoint & 0xffff000000000000ull) == kFreeEntryTag;
-#else
return (entrypoint & kFreeEntryTag) == kFreeEntryTag;
-#endif /* __illumos__ */
}
#endif
diff --git a/deps/v8/src/sandbox/js-dispatch-table.h b/deps/v8/src/sandbox/js-dispatch-table.h
index 830fa95fd3e..0912c4037eb 100644
--- a/deps/v8/src/sandbox/js-dispatch-table.h
+++ b/deps/v8/src/sandbox/js-dispatch-table.h
@@ -96,22 +96,7 @@ struct JSDispatchEntry {
#if defined(V8_TARGET_ARCH_64_BIT)
// Freelist entries contain the index of the next free entry in their lower 32
// bits and are tagged with this tag.
-#ifdef __illumos__
- // In illumos 64-bit apps, pointers are allocated both the bottom 2^47 range
- // AND the top 2^47 range in the 64-bit space. Instead of 47 bits of VA space
- // we have 48 bits. This means, however, the top 16-bits may be 0xffff. We
- // therefore pick a different value for the kFreeEntryTag. If/when we go to
- // VA57, aka 5-level paging, we'll need to revisit this again, as will node
- // by default, since the fixed-bits on the high end will shrink from top
- // 16-bits to top 8-bits.
- //
- // Unless illumos ships an Oracle-Solaris-like VA47 link-time options to
- // restrict pointers from allocating from above the Virtual Address hole,
- // we need to be mindful of this.
- static constexpr Address kFreeEntryTag = 0xfeed000000000000ull;
-#else
static constexpr Address kFreeEntryTag = 0xffff000000000000ull;
-#endif /* __illumos__ */
#ifdef V8_TARGET_BIG_ENDIAN
// 2-byte parameter count is on the least significant side of encoded_word_.
static constexpr int kBigEndianParamCountOffset =
diff --git a/deps/v8/src/sandbox/sandbox.cc b/deps/v8/src/sandbox/sandbox.cc
index e5368882ef0..894029b6e92 100644
--- a/deps/v8/src/sandbox/sandbox.cc
+++ b/deps/v8/src/sandbox/sandbox.cc
@@ -4,6 +4,7 @@
#include "src/sandbox/sandbox.h"
+#include <algorithm>
#include <memory>
#include "include/v8-internal.h"
@@ -115,33 +116,6 @@ void DefaultInSandboxAllocator::LazyInitialize() {
region_alloc_ = std::make_unique<base::RegionAllocator>(
backing_memory_base, backing_memory_size, kAllocationGranularity);
end_of_accessible_region_ = region_alloc_->begin();
-
- // Install an on-merge callback to discard or decommit unused pages.
- region_alloc_->set_on_merge_callback([this](Address start, size_t size) {
- mutex_.AssertHeld();
- Address end = start + size;
- if (end == region_alloc_->end() &&
- start <= end_of_accessible_region_ - kChunkSize) {
- // Can shrink the accessible region.
- Address new_end_of_accessible_region = RoundUp(start, kChunkSize);
- size_t size_to_decommit =
- end_of_accessible_region_ - new_end_of_accessible_region;
- if (!sandbox_->address_space()->DecommitPages(
- new_end_of_accessible_region, size_to_decommit)) {
- V8::FatalProcessOutOfMemory(nullptr, "SandboxedArrayBufferAllocator()");
- }
- end_of_accessible_region_ = new_end_of_accessible_region;
- } else if (size >= 2 * kChunkSize) {
- // Can discard pages. The pages stay accessible, so the size of the
- // accessible region doesn't change.
- Address chunk_start = RoundUp(start, kChunkSize);
- Address chunk_end = RoundDown(start + size, kChunkSize);
- if (!sandbox_->address_space()->DiscardSystemPages(
- chunk_start, chunk_end - chunk_start)) {
- V8::FatalProcessOutOfMemory(nullptr, "SandboxedArrayBufferAllocator()");
- }
- }
- });
}
DefaultInSandboxAllocator::~DefaultInSandboxAllocator() {
@@ -233,13 +207,43 @@ void DefaultInSandboxAllocator::Free(void* data) {
base::MutexGuard guard(&mutex_);
CHECK(is_initialized());
- region_alloc_->FreeRegion(reinterpret_cast<Address>(data));
+ Address address = reinterpret_cast<Address>(data);
+ base::AddressRegion free_region;
+ size_t size = region_alloc_->FreeRegion(address, &free_region);
+ if (size == 0) return;
+
+ // Return the memory of chunks that are now entirely free to the OS.
+ if (free_region.end() == region_alloc_->end() &&
+ free_region.begin() <= end_of_accessible_region_ - kChunkSize) {
+ // The free region reaches the end of the backing memory: shrink the
+ // accessible region.
+ Address new_end_of_accessible_region =
+ RoundUp(free_region.begin(), kChunkSize);
+ size_t size_to_decommit =
+ end_of_accessible_region_ - new_end_of_accessible_region;
+ if (!sandbox_->address_space()->DecommitPages(new_end_of_accessible_region,
+ size_to_decommit)) {
+ V8::FatalProcessOutOfMemory(nullptr, "SandboxedArrayBufferAllocator()");
+ }
+ end_of_accessible_region_ = new_end_of_accessible_region;
+ } else {
+ // Discard the pages; they stay accessible. Only chunks overlapping the
+ // freed region can have become entirely free: the rest of |free_region|
+ // was free before and was discarded when it became free.
+ Address chunk_start = std::max(RoundUp(free_region.begin(), kChunkSize),
+ RoundDown(address, kChunkSize));
+ Address chunk_end = std::min(RoundDown(free_region.end(), kChunkSize),
+ RoundUp(address + size, kChunkSize));
+ if (chunk_start < chunk_end &&
+ !sandbox_->address_space()->DiscardSystemPages(
+ chunk_start, chunk_end - chunk_start)) {
+ V8::FatalProcessOutOfMemory(nullptr, "SandboxedArrayBufferAllocator()");
+ }
+ }
}
} // namespace
-bool Sandbox::smi_address_range_reserved_ = false;
-
#ifdef V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES
thread_local Sandbox* Sandbox::current_ = nullptr;
// static
@@ -279,6 +283,10 @@ static Address DetermineAddressSpaceLimit() {
// configuration and there seems to be no easy way to retrieve the actual
// number of virtual address bits from the CPU in userspace.
hardware_virtual_address_bits = 40;
+#elif defined(V8_TARGET_ARCH_ARM64) && defined(V8_TARGET_OS_CHROMEOS)
+ // On Arm64 ChromeOS kernel is configured to have a 40-bit virtual address
+ // space (39 bits for userspace and kernel each).
+ hardware_virtual_address_bits = 40;
#elif defined(V8_TARGET_OS_IOS)
// On iOS, we only get 64 GB of userspace virtual address space even with the
// "jumbo" extended virtual addressing entitlement, so assume a 37-bit virtual
@@ -498,33 +506,9 @@ bool Sandbox::Initialize(v8::Platform* platform, v8::VirtualAddressSpace* vas,
back, kSandboxGuardRegionSize + kAdditionalTrailingGuardRegionSize));
}
- // Also try to reserve the first 4GB of the process' address space. This
- // mitigates Smi<->HeapObject confusion bugs in which we end up treating a
- // Smi value as a pointer.
- if (!smi_address_range_reserved_) {
- // Make the guard region extend a little past the first 4GB to also catch
- // accesses to in-object properties which are bounded by the JSObject
- // instance size.
- static_assert(kSmiAddressRangePadding > JSObject::kMaxInstanceSize);
- constexpr Address kRangeEnd = kSmiAddressRange + kSmiAddressRangePadding;
- const size_t zero_segment_size = platform->GetZeroSegmentSize();
- if (zero_segment_size >= kRangeEnd) {
- smi_address_range_reserved_ = true;
- } else {
- const size_t step = address_space_->allocation_granularity();
- const Address aligned_end = RoundUp(kRangeEnd, step);
- for (Address start = 0; start <= 1 * MB; start += step) {
- if (vas->AllocateGuardRegion(start, aligned_end - start)) {
- smi_address_range_reserved_ = true;
- break;
- }
- }
- }
- }
-
initialized_ = true;
- FinishInitialization();
+ FinishInitialization(platform);
DCHECK(!is_partially_reserved());
return true;
@@ -591,13 +575,22 @@ bool Sandbox::InitializeAsPartiallyReservedSandbox(v8::Platform* platform,
address_space_.get());
in_sandbox_allocator_ = std::make_shared<DefaultInSandboxAllocator>(this);
- FinishInitialization();
+ FinishInitialization(platform);
DCHECK(is_partially_reserved());
return true;
}
-void Sandbox::FinishInitialization() {
+void Sandbox::FinishInitialization(v8::Platform* platform) {
+ // Check whether the first 4GB of the process' address space are reserved.
+ // This mitigates Smi<->HeapObject confusion bugs in which we end up treating
+ // a Smi value as a pointer.
+ // Make the guard region extend a little past the first 4GB to also catch
+ // accesses to in-object properties which are bounded by the JSObject
+ // instance size.
+ static_assert(kSmiAddressRangePadding > JSObject::kMaxInstanceSize);
+ constexpr Address kRangeEnd = kSmiAddressRange + kSmiAddressRangePadding;
+ smi_address_range_reserved_ = platform->GetZeroSegmentSize() >= kRangeEnd;
#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
// We do this even for the case of partially-reserved sandbox because, while
// being an unsafe setup, tests and fuzzers shouldn't report crashes in this
@@ -656,6 +649,7 @@ void Sandbox::TearDown() {
reservation_base_ = kNullAddress;
reservation_size_ = 0;
initialized_ = false;
+ smi_address_range_reserved_ = false;
constants_.Reset();
}
}
diff --git a/deps/v8/src/sandbox/sandbox.h b/deps/v8/src/sandbox/sandbox.h
index d566a3f65ef..a5f97a97942 100644
--- a/deps/v8/src/sandbox/sandbox.h
+++ b/deps/v8/src/sandbox/sandbox.h
@@ -128,10 +128,10 @@ class V8_EXPORT_PRIVATE Sandbox {
/**
* Returns true if the first four GB of the address space are inaccessible.
*
- * During initialization, the sandbox will also attempt to create an
- * inaccessible mapping in the first four GB of the address space. This is
- * useful to mitigate Smi<->HeapObject confusion issues, in which a (32-bit)
- * Smi is treated as a pointer and dereferenced.
+ * During initialization, the sandbox checks whether the platform/allocator
+ * has reserved an inaccessible zero segment covering the first four GB of the
+ * address space. This is useful to mitigate Smi<->HeapObject confusion
+ * issues, in which a (32-bit) Smi is treated as a pointer and dereferenced.
*/
bool smi_address_range_is_inaccessible() const {
return smi_address_range_reserved_;
@@ -313,7 +313,7 @@ class V8_EXPORT_PRIVATE Sandbox {
// Performs final initialization steps after the sandbox address space has
// been initialized. Called from the two Initialize variants above.
- void FinishInitialization();
+ void FinishInitialization(v8::Platform* platform);
// Initialize the constant objects for this sandbox.
void InitializeConstants();
@@ -353,11 +353,12 @@ class V8_EXPORT_PRIVATE Sandbox {
// Constant objects inside this sandbox.
SandboxedPointerConstants constants_;
- // Besides the address space reservation for the sandbox, we also try to
- // reserve the first four gigabytes of the virtual address space (with an
- // inaccessible mapping). This for example mitigates Smi<->HeapObject
- // confusion bugs in which we treat a Smi value as a pointer and access it.
- static bool smi_address_range_reserved_;
+ // Besides the address space reservation for the sandbox, the first four
+ // gigabytes of the virtual address space may be reserved by the
+ // platform/allocator as an inaccessible zero segment. This for example
+ // mitigates Smi<->HeapObject confusion bugs in which we treat a Smi value as
+ // a pointer and access it.
+ bool smi_address_range_reserved_ = false;
#ifdef V8_COMPRESS_POINTERS_IN_MULTIPLE_CAGES
thread_local static Sandbox* current_;
diff --git a/deps/v8/src/sandbox/testing.cc b/deps/v8/src/sandbox/testing.cc
index 5dc89dd48d2..c459abf8156 100644
--- a/deps/v8/src/sandbox/testing.cc
+++ b/deps/v8/src/sandbox/testing.cc
@@ -4,6 +4,7 @@
#include "src/sandbox/testing.h"
+#include <atomic>
#include <cstring>
#include <vector>
@@ -877,6 +878,23 @@ void InstallFunction(Isolate* isolate, Handle<JSObject> holder,
InstallFunc(isolate, holder, func, name, num_parameters, false);
}
+// Sandbox.getMetadata() -> Object
+void SandboxGetMetadata(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ DCHECK(ValidateCallbackInfo(info));
+ v8::Isolate* isolate = info.GetIsolate();
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
+ Factory* factory = i_isolate->factory();
+
+ Handle<JSObject> metadata =
+ factory->NewJSObject(i_isolate->object_function());
+ JSObject::AddProperty(
+ i_isolate, metadata,
+ factory->NewStringFromAsciiChecked("trustedPointerHandleShift"),
+ factory->NewNumberFromUint(kTrustedPointerHandleShift), NONE);
+
+ info.GetReturnValue().Set(Utils::ToLocal(metadata));
+}
+
void InstallConstructor(Isolate* isolate, Handle<JSObject> holder,
FunctionCallback func, const char* name,
int num_parameters) {
@@ -900,6 +918,7 @@ void SandboxTesting::InstallMemoryCorruptionApi(Isolate* isolate) {
InstallGetter(isolate, sandbox, SandboxGetBase, "base");
InstallGetter(isolate, sandbox, SandboxGetByteLength, "byteLength");
InstallConstructor(isolate, sandbox, SandboxMemoryView, "MemoryView", 2);
+ InstallFunction(isolate, sandbox, SandboxGetMetadata, "getMetadata", 0);
InstallFunction(isolate, sandbox, SandboxGetAddressOf, "getAddressOf", 1);
InstallFunction(isolate, sandbox, SandboxGetObjectAt, "getObjectAt", 1);
InstallFunction(isolate, sandbox, SandboxIsValidObjectAt, "isValidObjectAt",
@@ -1076,6 +1095,11 @@ void FilterCrash(const char* reason) {
struct sigaction g_old_handlers[NSIG];
constexpr int kSignalsToHandle[] = {SIGABRT, SIGTRAP, SIGBUS, SIGILL, SIGSEGV};
+std::atomic<bool> g_is_sandbox_violation{false};
+#ifdef V8_USE_ADDRESS_SANITIZER
+bool g_is_asan_fault_harmless = false;
+#endif
+
void UninstallCrashFilter() {
// NOTE: This code MUST be async-signal safe.
// NO malloc or stdio is allowed here.
@@ -1092,8 +1116,8 @@ void UninstallCrashFilter() {
}
// We should also uninstall the sanitizer death callback as our crash filter
- // may hand a crash over to sanitizers, which should then not enter our crash
- // filtering logic a second time.
+ // may hand a crash over to sanitizers, which should then not print the
+ // sandbox violation message a second time.
#ifdef V8_USE_ANY_SANITIZER
__sanitizer_set_death_callback(nullptr);
#endif // V8_USE_ANY_SANITIZER
@@ -1306,6 +1330,8 @@ void CrashFilter(int signal, siginfo_t* info, void* context) {
// If we get here, we've detected a sandbox violation.
PrintToStderr("\n## V8 sandbox violation detected!\n\n");
+ g_is_sandbox_violation = true;
+
if (access_type == MemoryAccessType::kRead) {
PrintToStderr(
"The sandbox violation was a *read* access which is technically not a "
@@ -1332,6 +1358,8 @@ void CrashFilter(int signal, siginfo_t* info, void* context) {
}
#ifdef V8_USE_ADDRESS_SANITIZER
+namespace {
+
bool IsHarmlessMemcpyParamOverlap() {
const void* src_addr = nullptr;
size_t src_size = 0;
@@ -1364,32 +1392,78 @@ bool IsHarmlessMemcpyParamOverlap() {
sandbox->ReservationContains(dest_begin) &&
sandbox->ReservationContains(dest_last);
}
+
+bool IsHarmlessASanFault(const char* description, Address faultaddr,
+ MemoryAccessType access_type) {
+ if (description && strcmp(description, "memcpy-param-overlap") == 0) {
+ if (IsHarmlessMemcpyParamOverlap()) {
+ PrintToStderr(
+ "Caught harmless ASan fault (overlapping memcpy safely contained "
+ "in the sandbox).\n");
+ return true;
+ }
+ // Otherwise, treat it as a sandbox violation.
+ return false;
+ }
+
+ if (faultaddr == kNullAddress) {
+ PrintToStderr(
+ "Caught ASan fault without a fault address. Ignoring it as we cannot "
+ "check if it is a sandbox violation.\n");
+ return true;
+ }
+
+ if (IsCrashInSafeMemoryRegion(faultaddr, access_type)) {
+ PrintToStderr("Caught harmless ASan fault (inside safe region).\n");
+ return true;
+ }
+
+ return false;
+}
+} // namespace
+
+extern "C" V8_EXPORT_PRIVATE void __asan_on_error() {
+ if (SandboxTesting::mode() == SandboxTesting::Mode::kDisabled) return;
+
+ if (!__asan_report_present()) {
+ // Should not occur normally, but falling back to treating this as an error
+ // as defense-in-depth.
+ g_is_sandbox_violation = true;
+ return;
+ }
+
+ // Prevent unnecessary/confusing reporting if we already know the crash
+ // classification.
+ if (g_is_sandbox_violation) return;
+
+ const char* const description = __asan_get_report_description();
+ const Address faultaddr =
+ reinterpret_cast<Address>(__asan_get_report_address());
+ const MemoryAccessType access_type = __asan_get_report_access_type() == 0
+ ? MemoryAccessType::kRead
+ : MemoryAccessType::kWrite;
+ if (IsHarmlessASanFault(description, faultaddr, access_type)) {
+ g_is_asan_fault_harmless = true;
+ } else {
+ g_is_sandbox_violation = true;
+ }
+}
#endif // V8_USE_ADDRESS_SANITIZER
#ifdef V8_USE_ANY_SANITIZER
void SanitizerFaultHandler() {
#ifdef V8_USE_ADDRESS_SANITIZER
- if (__asan_report_present()) {
- const char* const description = __asan_get_report_description();
- const Address faultaddr =
- reinterpret_cast<Address>(__asan_get_report_address());
- const MemoryAccessType access_type = __asan_get_report_access_type() == 0
- ? MemoryAccessType::kRead
- : MemoryAccessType::kWrite;
- if (description && strcmp(description, "memcpy-param-overlap") == 0) {
- if (IsHarmlessMemcpyParamOverlap()) {
- FilterCrash(
- "Caught harmless ASan fault (overlapping memcpy safely contained "
- "in the sandbox).");
- }
- // Otherwise, fall through to the sandbox report.
- } else if (faultaddr == kNullAddress) {
- FilterCrash(
- "Caught ASan fault without a fault address. Ignoring it as we cannot "
- "check if it is a sandbox violation.");
- } else if (IsCrashInSafeMemoryRegion(faultaddr, access_type)) {
- FilterCrash("Caught harmless ASan fault (inside safe region).");
- }
+ if (!g_is_sandbox_violation && !g_is_asan_fault_harmless) {
+ PrintToStderr(
+ "Warning: ASan death callback triggered before the fault could be "
+ "classified. Falling back to treating it as a sandbox violation.\n");
+ }
+
+ if (g_is_asan_fault_harmless && !g_is_sandbox_violation) {
+ PrintToStderr("Exiting process after harmless fault...\n");
+ int status =
+ SandboxTesting::mode() == SandboxTesting::Mode::kForFuzzing ? -1 : 0;
+ _exit(status);
}
#endif // V8_USE_ADDRESS_SANITIZER
@@ -1425,8 +1499,8 @@ void InstallCrashFilter() {
CHECK(success);
#ifdef V8_USE_ANY_SANITIZER
- // We install sanitizer specific crash handlers. These can only check for
- // in-sandbox crashes on certain configurations.
+ // We install a sanitizer death callback. For ASan, this will check the flag
+ // set by __asan_on_error to determine if the fault was harmless.
//
// The crash handler also resets the signal handler as sanitizer may use
// `abort()` via `abort_on_error=1` option to signal problems.
diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc
index 9db502d38a2..99d934927d4 100644
--- a/deps/v8/src/snapshot/deserializer.cc
+++ b/deps/v8/src/snapshot/deserializer.cc
@@ -512,19 +512,7 @@ void NoExternalReferencesCallback() {
void PostProcessExternalString(Tagged<ExternalString> string,
Isolate* isolate) {
DisallowGarbageCollection no_gc;
- uint32_t index = string->GetResourceRefForDeserialization();
- // Our (sandbox) fuzzers can sometimes get here by mutating an in-sandbox
- // object after deserialization but before post-processing, and making it
- // look like an ExternalString. In that case, the Isolate may not have any
- // external references and this CHECK then avoids false-positive crashes.
- // Technically we should probably also check that the index is in-bounds if
- // we do have external references on the Isolate, but in our current fuzzer
- // setup, this doesn't seem to be the case.
- CHECK_NE(isolate->api_external_references(), nullptr);
- Address address =
- static_cast<Address>(isolate->api_external_references()[index]);
- string->InitExternalPointerFields(isolate);
- string->set_address_as_resource(isolate, address);
+ string->InitResourceDataAfterDeserialization(isolate);
isolate->heap()->UpdateExternalString(string, 0,
string->ExternalPayloadSize());
isolate->heap()->RegisterExternalString(string);
@@ -557,20 +545,17 @@ void Deserializer<Isolate>::PostProcessNewJSReceiver(
}
} else if (InstanceTypeChecker::IsJSTypedArray(instance_type)) {
auto typed_array = Cast<JSTypedArray>(*obj);
+ uint32_t store_index = source_.GetUint30();
// Note: ByteArray objects must not be deferred s.t. they are
// available here for is_on_heap(). See also: CanBeDeferred.
// Fixup typed array pointers.
if (typed_array->is_on_heap()) {
- typed_array->AddExternalPointerCompensationForDeserialization(
- main_thread_isolate());
+ typed_array->InitOnHeapDataPtrAfterDeserialization(main_thread_isolate());
} else {
- // Serializer writes backing store ref as a DataPtr() value.
- uint32_t store_index =
- typed_array->GetExternalBackingStoreRefForDeserialization();
- auto backing_store = backing_stores_[store_index];
- if (backing_store && backing_store->buffer_start()) {
+ auto bs = backing_store(store_index);
+ if (bs && bs->buffer_start()) {
typed_array->SetOffHeapDataPtr(main_thread_isolate(),
- backing_store->buffer_start(),
+ bs->buffer_start(),
typed_array->byte_offset());
} else {
// Directly set the data pointer to point to the
@@ -583,7 +568,7 @@ void Deserializer<Isolate>::PostProcessNewJSReceiver(
}
} else if (InstanceTypeChecker::IsJSArrayBuffer(instance_type)) {
auto buffer = Cast<JSArrayBuffer>(*obj);
- uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
+ uint32_t store_index = source_.GetUint30();
buffer->init_extension();
if (store_index == kEmptyBackingStoreRefSentinel) {
buffer->set_backing_store(main_thread_isolate(),
diff --git a/deps/v8/src/snapshot/serializer.cc b/deps/v8/src/snapshot/serializer.cc
index 9c5161c76e8..337fc8b243e 100644
--- a/deps/v8/src/snapshot/serializer.cc
+++ b/deps/v8/src/snapshot/serializer.cc
@@ -287,6 +287,10 @@ void Serializer::PutRoot(RootIndex root) {
PrintF("\n");
}
+ SBXCHECK_IMPLIES(RootsTable::IsInTrustedObjectMapList(root),
+ RootsTable::IsInSerializableTrustedObjectMapList(root) ||
+ allow_serializing_all_trusted_objects());
+
// Assert that the first 32 root array items are a conscious choice. They are
// chosen so that the most common ones can be encoded more efficiently.
static_assert(static_cast<int>(RootIndex::kArgumentsMarker) ==
@@ -614,54 +618,44 @@ uint32_t Serializer::ObjectSerializer::SerializeBackingStore(
}
void Serializer::ObjectSerializer::SerializeJSTypedArray() {
+ uint32_t ref = kEmptyBackingStoreRefSentinel;
{
DisallowGarbageCollection no_gc;
Tagged<JSTypedArray> typed_array = Cast<JSTypedArray>(*object_);
- if (typed_array->is_on_heap()) {
- typed_array->RemoveExternalPointerCompensationForSerialization(isolate());
- } else {
- if (!typed_array->IsDetachedOrOutOfBounds()) {
- // Explicitly serialize the backing store now.
- Tagged<JSArrayBuffer> buffer =
- Cast<JSArrayBuffer>(typed_array->buffer());
- // We cannot store byte_length or max_byte_length larger than uint32
- // range in the snapshot.
- size_t byte_length_size = buffer->GetByteLength();
- CHECK_LE(byte_length_size,
- size_t{std::numeric_limits<uint32_t>::max()});
- uint32_t byte_length = static_cast<uint32_t>(byte_length_size);
- Maybe<uint32_t> max_byte_length = Nothing<uint32_t>();
- if (buffer->is_resizable_by_js()) {
- CHECK_LE(buffer->max_byte_length(),
- std::numeric_limits<uint32_t>::max());
- max_byte_length =
- Just(static_cast<uint32_t>(buffer->max_byte_length()));
- }
- size_t byte_offset = typed_array->byte_offset();
+ if (!typed_array->is_on_heap() && !typed_array->IsDetachedOrOutOfBounds()) {
+ // Explicitly serialize the backing store now.
+ Tagged<JSArrayBuffer> buffer = Cast<JSArrayBuffer>(typed_array->buffer());
+ // We cannot store byte_length or max_byte_length larger than uint32
+ // range in the snapshot.
+ size_t byte_length_size = buffer->GetByteLength();
+ CHECK_LE(byte_length_size, size_t{std::numeric_limits<uint32_t>::max()});
+ uint32_t byte_length = static_cast<uint32_t>(byte_length_size);
+ Maybe<uint32_t> max_byte_length = Nothing<uint32_t>();
+ if (buffer->is_resizable_by_js()) {
+ CHECK_LE(buffer->max_byte_length(),
+ std::numeric_limits<uint32_t>::max());
+ max_byte_length =
+ Just(static_cast<uint32_t>(buffer->max_byte_length()));
+ }
+ size_t byte_offset = typed_array->byte_offset();
- // We need to calculate the backing store from the data pointer
- // because the ArrayBuffer may already have been serialized.
- void* backing_store = reinterpret_cast<void*>(
- reinterpret_cast<Address>(typed_array->DataPtr()) - byte_offset);
+ // We need to calculate the backing store from the data pointer
+ // because the ArrayBuffer may already have been serialized.
+ void* backing_store = reinterpret_cast<void*>(
+ reinterpret_cast<Address>(typed_array->DataPtr()) - byte_offset);
- uint32_t ref =
- SerializeBackingStore(backing_store, byte_length, max_byte_length);
- typed_array->SetExternalBackingStoreRefForSerialization(ref);
- } else {
- typed_array->SetExternalBackingStoreRefForSerialization(0);
- }
+ ref = SerializeBackingStore(backing_store, byte_length, max_byte_length);
}
}
SerializeObject();
+ sink_->PutUint30(ref, "BackingStoreRef");
}
void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
- ArrayBufferExtension* extension;
- void* backing_store;
+ uint32_t ref = kEmptyBackingStoreRefSentinel;
{
DisallowGarbageCollection no_gc;
Tagged<JSArrayBuffer> buffer = Cast<JSArrayBuffer>(*object_);
- backing_store = buffer->backing_store();
// We cannot store byte_length or max_byte_length larger than uint32 range
// in the snapshot.
size_t byte_length_size = buffer->GetByteLength();
@@ -672,27 +666,15 @@ void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
CHECK_LE(buffer->max_byte_length(), std::numeric_limits<uint32_t>::max());
max_byte_length = Just(static_cast<uint32_t>(buffer->max_byte_length()));
}
- extension = buffer->extension();
// Only serialize non-empty backing stores.
- if (buffer->IsEmpty()) {
- buffer->SetBackingStoreRefForSerialization(kEmptyBackingStoreRefSentinel);
- } else {
- uint32_t ref =
- SerializeBackingStore(backing_store, byte_length, max_byte_length);
- buffer->SetBackingStoreRefForSerialization(ref);
+ if (!buffer->IsEmpty()) {
+ ref = SerializeBackingStore(buffer->backing_store(), byte_length,
+ max_byte_length);
}
-
- // Ensure deterministic output by setting extension to null during
- // serialization.
- buffer->set_extension(nullptr);
}
SerializeObject();
- {
- Tagged<JSArrayBuffer> buffer = Cast<JSArrayBuffer>(*object_);
- buffer->set_backing_store(isolate(), backing_store);
- buffer->set_extension(extension);
- }
+ sink_->PutUint30(ref, "BackingStoreRef");
}
void Serializer::ObjectSerializer::SerializeNativeContext() {
@@ -705,20 +687,16 @@ void Serializer::ObjectSerializer::SerializeNativeContext() {
}
void Serializer::ObjectSerializer::SerializeExternalString() {
- // For external strings with known resources, we replace the resource field
- // with the encoded external reference, which we restore upon deserialize.
- // For the rest we serialize them to look like ordinary sequential strings.
+ // For external strings with known resources, their external pointer slots
+ // are serialized via VisitExternalPointer. For the rest we serialize them
+ // to look like ordinary sequential strings.
auto string = Cast<ExternalString>(object_);
Address resource = string->resource_as_address(isolate());
ExternalReferenceEncoder::Value reference;
if (serializer_->external_reference_encoder_.TryEncode(resource).To(
&reference)) {
DCHECK(reference.is_from_api());
- // The string stays live in this isolate, so both external pointer fields
- // have to be put back once it has been serialized.
- auto refs = string->SetResourceRefForSerialization(reference.index());
SerializeObject();
- string->RestoreResourceRefs(isolate(), refs);
} else {
SerializeExternalStringAsSequentialString();
}
@@ -1161,7 +1139,9 @@ void Serializer::ObjectSerializer::VisitExternalPointer(
InstanceTypeChecker::IsJSExternalObject(instance_type) ||
InstanceTypeChecker::IsAccessorInfo(instance_type) ||
InstanceTypeChecker::IsInterceptorInfo(instance_type) ||
- InstanceTypeChecker::IsFunctionTemplateInfo(instance_type)) {
+ InstanceTypeChecker::IsFunctionTemplateInfo(instance_type) ||
+ InstanceTypeChecker::IsJSArrayBuffer(instance_type) ||
+ InstanceTypeChecker::IsExternalString(instance_type)) {
// If necessary, output any raw data preceding this slot.
OutputRawData(slot.address());
#ifdef V8_ENABLE_SANDBOX
@@ -1178,6 +1158,15 @@ void Serializer::ObjectSerializer::VisitExternalPointer(
Address value = slot.load(isolate());
ExternalPointerTag tag = kExternalPointerNullTag;
#endif // V8_ENABLE_SANDBOX
+ if (slot.tag_range() == kExternalStringResourceDataTag ||
+ slot.tag_range() == kArrayBufferExtensionTag) {
+ // resource_data_ is initialized in PostProcessExternalString, and
+ // extension_ in PostProcessNewJSReceiver. Serializing them as null also
+ // keeps the snapshot deterministic, as both hold values that are only
+ // meaningful within the serializing isolate.
+ value = kNullAddress;
+ tag = kExternalPointerNullTag;
+ }
const bool sandboxify = V8_ENABLE_SANDBOX_BOOL;
OutputExternalReference(value, kSystemPointerSize, sandboxify, tag);
bytes_processed_so_far_ += kExternalPointerSlotSize;
@@ -1185,12 +1174,6 @@ void Serializer::ObjectSerializer::VisitExternalPointer(
// Serialization of external references in other objects is handled
// elsewhere or not supported.
DCHECK(
- // See ObjectSerializer::SerializeJSTypedArray().
- InstanceTypeChecker::IsJSTypedArray(instance_type) ||
- // See ObjectSerializer::SerializeJSArrayBuffer().
- InstanceTypeChecker::IsJSArrayBuffer(instance_type) ||
- // See ObjectSerializer::SerializeExternalString().
- InstanceTypeChecker::IsExternalString(instance_type) ||
// Serialization of external pointers stored in
// JSSynchronizationPrimitive is not supported.
// TODO(v8:12547): JSSynchronizationPrimitives should also be sanitized
@@ -1326,6 +1309,7 @@ void Serializer::ObjectSerializer::VisitJSDispatchTableEntry(
// Currently we cannot see pending objects here, but we may need to support
// them in the future. They should already be supported by the deserializer.
Handle<Code> code(jdt.GetCode(handle), isolate());
+ SBXCHECK(code->is_builtin());
CHECK(!serializer_->SerializePendingObject(*code));
serializer_->SerializeObject(code, SlotType::kAnySlot);
} else {
@@ -1399,6 +1383,22 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
Code::kInstructionStartOffset,
sizeof(field_value), field_value);
+ } else if (IsJSTypedArray(*object_)) {
+ // The external_pointer field contains a raw value that will be
+ // recomputed after deserialization, so write zeros to keep the snapshot
+ // deterministic.
+ static uint8_t field_value[kSystemPointerSize] = {0};
+ OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
+ offsetof(JSTypedArray, external_pointer_),
+ sizeof(field_value), field_value);
+ } else if (IsJSArrayBuffer(*object_)) {
+ // The backing_store field contains a raw value that will be
+ // recomputed after deserialization, so write zeros to keep the snapshot
+ // deterministic.
+ static uint8_t field_value[kSystemPointerSize] = {0};
+ OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
+ offsetof(JSArrayBuffer, backing_store_),
+ sizeof(field_value), field_value);
} else if (IsSeqString(*object_)) {
// SeqStrings may contain padding. Serialize the padding bytes as 0s to
// make the snapshot content deterministic.
diff --git a/deps/v8/src/snapshot/serializer.h b/deps/v8/src/snapshot/serializer.h
index 318f24a804f..85d3556be70 100644
--- a/deps/v8/src/snapshot/serializer.h
+++ b/deps/v8/src/snapshot/serializer.h
@@ -323,6 +323,9 @@ class Serializer : public SerializerDeserializer {
return (flags_ &
Snapshot::kReconstructReadOnlyAndSharedObjectCachesForTesting) != 0;
}
+ bool allow_serializing_all_trusted_objects() const {
+ return (flags_ & Snapshot::kAllowSerializingAllTrustedObjects) != 0;
+ }
bool deferred_objects_empty() { return deferred_objects_.size() == 0; }
diff --git a/deps/v8/src/snapshot/snapshot.cc b/deps/v8/src/snapshot/snapshot.cc
index 5e228aebb35..90b6076caba 100644
--- a/deps/v8/src/snapshot/snapshot.cc
+++ b/deps/v8/src/snapshot/snapshot.cc
@@ -409,6 +409,7 @@ v8::StartupData Snapshot::Create(
DCHECK_GT(contexts->size(), 0);
HandleScope scope(isolate);
+ flags |= Snapshot::kAllowSerializingAllTrustedObjects;
ReadOnlySerializer read_only_serializer(isolate, flags);
read_only_serializer.Serialize();
diff --git a/deps/v8/src/snapshot/snapshot.h b/deps/v8/src/snapshot/snapshot.h
index e6123ef3860..f661fb4e6e8 100644
--- a/deps/v8/src/snapshot/snapshot.h
+++ b/deps/v8/src/snapshot/snapshot.h
@@ -52,6 +52,11 @@ class Snapshot : public AllStatic {
// objects are serialized, and the shared heap object cache is populated as
// shared heap objects are serialized.
kReconstructReadOnlyAndSharedObjectCachesForTesting = 1 << 2,
+ // If set, allows serializing trusted objects whose maps are not in
+ // SERIALIZABLE_TRUSTED_OBJECT_MAP_ROOT_LIST. This is enabled for snapshot
+ // serialization, while code serialization disallows non-serializable
+ // trusted objects by default.
+ kAllowSerializingAllTrustedObjects = 1 << 3,
};
using SerializerFlags = base::Flags<SerializerFlag>;
V8_EXPORT_PRIVATE static constexpr SerializerFlags kDefaultSerializerFlags =
diff --git a/deps/v8/src/snapshot/static-roots-gen.cc b/deps/v8/src/snapshot/static-roots-gen.cc
index a3fd623cf41..0ed189cc975 100644
--- a/deps/v8/src/snapshot/static-roots-gen.cc
+++ b/deps/v8/src/snapshot/static-roots-gen.cc
@@ -122,26 +122,42 @@ void StaticRootsTableGen::write(Isolate* isolate, const char* file) {
static const char* kPreString = " static constexpr Tagged_t k";
const std::string& name = gen.camel_name(root);
- out << kPreString << name << " =";
-
- // Emit absolute values for constants we need to copy to other files.
- if (prev_ptr == 0 || ptr > 0xff00 || root == RootIndex::kUndefinedValue ||
- root == RootIndex::kNullValue || root == RootIndex::kTrueValue ||
- root == RootIndex::kFalseValue || root == RootIndex::kempty_string) {
- size_t ptr_len = ptr == 0 ? 1 : ceil(log2(ptr) / 4.0);
- // Full line is: "kPreString|name = 0x.....;"
- size_t len = strlen(kPreString) + name.length() + 5 + ptr_len + 1;
- if (len > 80) out << "\n ";
- out << " 0x" << std::hex << ptr << std::dec << ";\n";
+ // TODO(leszeks): Remove DisabledTdzHole special-casing when
+ // v8_enable_tdz_hole is removed.
+ if (name == "TdzHoleValue" || name == "DisabledTdzHoleValue") {
+ out << " // TODO(leszeks): Remove DisabledTdzHole when "
+ "v8_enable_tdz_hole is removed.\n"
+ << "#ifdef V8_ENABLE_TDZ_HOLE\n"
+ << kPreString << "TdzHoleValue = 0x" << std::hex << ptr << std::dec
+ << ";\n"
+ << "#else\n"
+ << kPreString << "DisabledTdzHoleValue = 0x" << std::hex << ptr
+ << std::dec << ";\n"
+ << "#endif\n";
} else {
- // Otherwise emit relative definitions to reduce churn.
- std::string rel_str =
- " k" + prev_name + " + " + std::to_string(ptr - prev_ptr);
- // Full line is: "kPreString|name = k|prev_name + .....;"
- size_t len =
- strlen(kPreString) + name.length() + 2 + rel_str.length() + 1;
- if (len > 80) out << "\n ";
- out << rel_str << ";\n";
+ out << kPreString << name << " =";
+
+ // Emit absolute values for constants we need to copy to other files.
+ if (prev_ptr == 0 || ptr > 0xff00 ||
+ root == RootIndex::kUndefinedValue ||
+ root == RootIndex::kNullValue || root == RootIndex::kTrueValue ||
+ root == RootIndex::kFalseValue ||
+ root == RootIndex::kempty_string) {
+ size_t ptr_len = ptr == 0 ? 1 : ceil(log2(ptr) / 4.0);
+ // Full line is: "kPreString|name = 0x.....;"
+ size_t len = strlen(kPreString) + name.length() + 5 + ptr_len + 1;
+ if (len > 80) out << "\n ";
+ out << " 0x" << std::hex << ptr << std::dec << ";\n";
+ } else {
+ // Otherwise emit relative definitions to reduce churn.
+ std::string rel_str =
+ " k" + prev_name + " + " + std::to_string(ptr - prev_ptr);
+ // Full line is: "kPreString|name = k|prev_name + .....;"
+ size_t len =
+ strlen(kPreString) + name.length() + 2 + rel_str.length() + 1;
+ if (len > 80) out << "\n ";
+ out << rel_str << ";\n";
+ }
}
prev_name = name;
@@ -161,8 +177,21 @@ void StaticRootsTableGen::write(Isolate* isolate, const char* file) {
<< "> StaticReadOnlyRootsPointerTable = {\n";
{
-#define ENTRY(_1, _2, CamelName) \
- out << " StaticReadOnlyRoot::k" << #CamelName << ",\n";
+ // TODO(leszeks): Remove DisabledTdzHole special-casing when
+ // v8_enable_tdz_hole is removed.
+#define ENTRY(_1, _2, CamelName) \
+ if (std::string_view(#CamelName) == "TdzHoleValue" || \
+ std::string_view(#CamelName) == "DisabledTdzHoleValue") { \
+ out << " // TODO(leszeks): Remove DisabledTdzHole when " \
+ "v8_enable_tdz_hole is removed.\n" \
+ << "#ifdef V8_ENABLE_TDZ_HOLE\n" \
+ << " StaticReadOnlyRoot::kTdzHoleValue,\n" \
+ << "#else\n" \
+ << " StaticReadOnlyRoot::kDisabledTdzHoleValue,\n" \
+ << "#endif\n"; \
+ } else { \
+ out << " StaticReadOnlyRoot::k" << #CamelName << ",\n"; \
+ }
READ_ONLY_ROOT_LIST(ENTRY)
#undef ENTRY
out << "};\n";
diff --git a/deps/v8/src/strings/string-hasher-inl.h b/deps/v8/src/strings/string-hasher-inl.h
index 1308c98a7e8..14b63120c20 100644
--- a/deps/v8/src/strings/string-hasher-inl.h
+++ b/deps/v8/src/strings/string-hasher-inl.h
@@ -313,6 +313,7 @@ uint32_t StringHasher::HashSequentialString(const char_t* chars_raw,
switch (detail::TryParseArrayIndex(chars, length, i, index)) {
case detail::kSuccess: {
DCHECK_LE(index, String::kMaxArrayIndex);
+ if (out_one_byte_content) *out_one_byte_content = true;
return StringHasher::MakeArrayIndexHash(static_cast<uint32_t>(index),
length, seed);
}
diff --git a/deps/v8/src/strings/string-stream.cc b/deps/v8/src/strings/string-stream.cc
index 669e1e19118..edfa98f7d71 100644
--- a/deps/v8/src/strings/string-stream.cc
+++ b/deps/v8/src/strings/string-stream.cc
@@ -421,7 +421,10 @@ void StringStream::PrintPrototype(Isolate* isolate, Tagged<JSFunction> fun,
Tagged<Object> receiver) {
Tagged<Object> name = fun->shared()->Name();
bool print_name = false;
- if (IsNullOrUndefined(receiver) || IsTheHole(receiver) ||
+#ifdef V8_ENABLE_TDZ_HOLE
+ DCHECK(!IsTheHole(receiver));
+#endif
+ if (IsNullOrUndefined(receiver) || IsTdzHole(receiver) ||
IsJSProxy(receiver) || IsWasmObject(receiver)) {
print_name = true;
} else if (!isolate->context().is_null()) {
diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc
index ecfd37f1ff3..eec2a04006d 100644
--- a/deps/v8/src/torque/implementation-visitor.cc
+++ b/deps/v8/src/torque/implementation-visitor.cc
@@ -4029,11 +4029,6 @@ class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
std::string parent_name = use_templates ? "P" : parent->name();
if (type->IsLayoutDefinedInCpp()) {
- if (parent) {
- if (std::optional<size_t> packed_size = parent->size().SingleValue()) {
- return std::to_string(*packed_size);
- }
- }
return "sizeof(" + parent_name + ")";
}
@@ -4122,8 +4117,7 @@ void CppClassGenerator::GenerateCppObjectLayoutDefinitionAsserts() {
<< "::" << f.name_and_type.name << " in C++ do not match\");\n";
}
if (!type_->IsAbstract() && type_->HasStaticSize()) {
- impl_ << " static_assert(kSize <= sizeof(" + name_ + ") && sizeof(" +
- name_ + ") < kSize + alignof(" + name_ + "));\n";
+ impl_ << " static_assert(kSize == sizeof(" + name_ + "));\n";
}
impl_ << "};\n\n";
diff --git a/deps/v8/src/torque/torque-parser.cc b/deps/v8/src/torque/torque-parser.cc
index 3511bec33fd..14736cb2ee9 100644
--- a/deps/v8/src/torque/torque-parser.cc
+++ b/deps/v8/src/torque/torque-parser.cc
@@ -88,6 +88,11 @@ class BuildFlags : public base::ContextualClass<BuildFlags> {
build_flags_["V8_ENABLE_SEEDED_ARRAY_INDEX_HASH"] = true;
#else
build_flags_["V8_ENABLE_SEEDED_ARRAY_INDEX_HASH"] = false;
+#endif
+#ifdef V8_IS_TSAN
+ build_flags_["V8_IS_TSAN"] = true;
+#else
+ build_flags_["V8_IS_TSAN"] = false;
#endif
}
static bool GetFlag(const std::string& name, const char* production) {
diff --git a/deps/v8/src/torque/utils.cc b/deps/v8/src/torque/utils.cc
index ccdbecf9c2f..767ed953d4b 100644
--- a/deps/v8/src/torque/utils.cc
+++ b/deps/v8/src/torque/utils.cc
@@ -179,7 +179,8 @@ bool ContainsUpperCase(const std::string& s) {
// These do not need to follow the default naming convention for constants.
bool IsKeywordLikeName(std::string_view s) {
static const char* const keyword_like_constants[]{
- "True", "False", "TheHole", "PromiseHole", "Null", "Undefined"};
+ "True", "False", "TheHole", "TdzHole",
+ "PromiseHole", "Null", "Undefined"};
return std::find(std::begin(keyword_like_constants),
std::end(keyword_like_constants),
diff --git a/deps/v8/src/tracing/perfetto-logger.cc b/deps/v8/src/tracing/perfetto-logger.cc
index fdfa0c2fd9f..242de086df5 100644
--- a/deps/v8/src/tracing/perfetto-logger.cc
+++ b/deps/v8/src/tracing/perfetto-logger.cc
@@ -499,8 +499,7 @@ void PerfettoLogger::CodeDeoptEvent(DirectHandle<Code> code,
DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) {}
void PerfettoLogger::CodeDependencyChangeEvent(
- DirectHandle<Code> code, DirectHandle<SharedFunctionInfo> shared,
- const char* reason) {}
+ Tagged<Code> code, Tagged<SharedFunctionInfo> shared, const char* reason) {}
void PerfettoLogger::WeakCodeClearEvent() {}
bool PerfettoLogger::is_listening_to_code_events() { return true; }
diff --git a/deps/v8/src/tracing/perfetto-logger.h b/deps/v8/src/tracing/perfetto-logger.h
index a4995f41600..8386b20e4c1 100644
--- a/deps/v8/src/tracing/perfetto-logger.h
+++ b/deps/v8/src/tracing/perfetto-logger.h
@@ -68,8 +68,8 @@ class PerfettoLogger : public LogEventListener {
DirectHandle<SharedFunctionInfo> shared) override;
void CodeDeoptEvent(DirectHandle<Code> code, DeoptimizeKind kind, Address pc,
int fp_to_sp_delta) override;
- void CodeDependencyChangeEvent(DirectHandle<Code> code,
- DirectHandle<SharedFunctionInfo> shared,
+ void CodeDependencyChangeEvent(Tagged<Code> code,
+ Tagged<SharedFunctionInfo> shared,
const char* reason) override;
void WeakCodeClearEvent() override;
bool is_listening_to_code_events() override;
diff --git a/deps/v8/src/tracing/trace-categories.h b/deps/v8/src/tracing/trace-categories.h
index 26a89e56755..20334836ad5 100644
--- a/deps/v8/src/tracing/trace-categories.h
+++ b/deps/v8/src/tracing/trace-categories.h
@@ -38,6 +38,8 @@ PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(
perfetto::Category(TRACE_DISABLED_BY_DEFAULT("v8.cpu_profiler"))
.SetTags("slow"),
perfetto::Category(TRACE_DISABLED_BY_DEFAULT("v8.gc")).SetTags("slow"),
+ perfetto::Category(TRACE_DISABLED_BY_DEFAULT("v8.gc_extra"))
+ .SetTags("slow"),
perfetto::Category(TRACE_DISABLED_BY_DEFAULT("v8.gc_stats"))
.SetTags("slow"),
perfetto::Category(TRACE_DISABLED_BY_DEFAULT("v8.inspector"))
diff --git a/deps/v8/src/tracing/trace-event-no-perfetto.h b/deps/v8/src/tracing/trace-event-no-perfetto.h
index 99e8cd98466..033f720de1a 100644
--- a/deps/v8/src/tracing/trace-event-no-perfetto.h
+++ b/deps/v8/src/tracing/trace-event-no-perfetto.h
@@ -35,6 +35,13 @@ void Ignore(Args&&... args) {}
// perfetto::StaticString/DynamicString/Track/Flow.
namespace perfetto {
+// The stubs live in an inline namespace so that their mangled names can never
+// collide with the real perfetto SDK. Embedders may link the real SDK into the
+// same binary as a V8 built without V8_USE_PERFETTO; without the inline
+// namespace, any stub member function that is not inlined (e.g. at -O0 or with
+// -fno-inline) is resolved by the linker against the real, ABI-incompatible
+// implementation.
+inline namespace v8_stub {
class EventContext;
class StaticString {
@@ -108,7 +115,7 @@ struct TerminatingFlow {
return TerminatingFlow();
}
};
-
+} // namespace v8_stub
} // namespace perfetto
// This is the legacy implementation of tracing macros. There have been two
diff --git a/deps/v8/src/utils/version.cc b/deps/v8/src/utils/version.cc
index 7423f45762d..550db661144 100644
--- a/deps/v8/src/utils/version.cc
+++ b/deps/v8/src/utils/version.cc
@@ -6,7 +6,9 @@
#include "include/v8-version-string.h"
#include "include/v8-version.h"
+#include "src/base/hashing.h"
#include "src/base/strings.h"
+#include "src/base/vector.h"
// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
@@ -25,6 +27,13 @@ bool Version::candidate_ = (V8_IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = V8_VERSION_STRING;
+uint32_t Version::Hash() {
+ base::Hasher hasher;
+ hasher.Add(major_).Add(minor_).Add(build_).Add(patch_);
+ hasher.AddRange(base::OneByteVector(embedder_));
+ return static_cast<uint32_t>(hasher.hash());
+}
+
// Calculate the V8 version string.
void Version::GetString(base::Vector<char> str) {
const char* candidate = IsCandidate() ? " (candidate)" : "";
diff --git a/deps/v8/src/utils/version.h b/deps/v8/src/utils/version.h
index 1bae3e72371..0a0134e0437 100644
--- a/deps/v8/src/utils/version.h
+++ b/deps/v8/src/utils/version.h
@@ -7,7 +7,7 @@
#include <cstdint>
-#include "src/base/hashing.h"
+#include "include/v8config.h"
namespace v8 {
@@ -27,10 +27,7 @@ class V8_EXPORT Version {
static int GetPatch() { return patch_; }
static const char* GetEmbedder() { return embedder_; }
static bool IsCandidate() { return candidate_; }
- static uint32_t Hash() {
- return static_cast<uint32_t>(
- base::hash_combine(major_, minor_, build_, patch_));
- }
+ static uint32_t Hash();
// Calculate the V8 version string.
static void GetString(base::Vector<char> str);
@@ -55,6 +52,7 @@ class V8_EXPORT Version {
friend void SetVersion(int major, int minor, int build, int patch,
const char* embedder, bool candidate,
const char* soname);
+ friend class ScopedVersionEmbedderString;
};
} // namespace internal
diff --git a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64-inl.h b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64-inl.h
index 72a0c15e7b6..57476d65f3a 100644
--- a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64-inl.h
+++ b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64-inl.h
@@ -314,22 +314,10 @@ void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
}
void LiftoffAssembler::AlignFrameSize() {
- // The frame_size includes the frame marker. The frame marker has already been
- // pushed on the stack though, so we don't need to allocate memory for it
- // anymore.
- int frame_size = GetTotalFrameSize() - 2 * kSystemPointerSize;
-
- static_assert(kStackSlotSize == kXRegSize,
- "kStackSlotSize must equal kXRegSize");
-
// The stack pointer is required to be quadword aligned.
// Misalignment will cause a stack alignment fault.
- int misalignment = frame_size % kQuadWordSizeInBytes;
- if (misalignment) {
- int padding = kQuadWordSizeInBytes - misalignment;
- frame_size += padding;
- max_used_spill_offset_ += padding;
- }
+ max_used_spill_offset_ =
+ RoundUp(max_used_spill_offset_, kQuadWordSizeInBytes);
}
void LiftoffAssembler::PatchPrepareStackFrame(
diff --git a/deps/v8/src/wasm/baseline/liftoff-assembler.h b/deps/v8/src/wasm/baseline/liftoff-assembler.h
index c4e8c349880..3443ca9f670 100644
--- a/deps/v8/src/wasm/baseline/liftoff-assembler.h
+++ b/deps/v8/src/wasm/baseline/liftoff-assembler.h
@@ -393,8 +393,9 @@ class LiftoffAssembler : public MacroAssembler {
CacheState& operator=(const CacheState&) V8_NOEXCEPT = default;
};
- explicit LiftoffAssembler(Zone*, std::unique_ptr<AssemblerBuffer>);
- ~LiftoffAssembler() override;
+ V8_EXPORT_PRIVATE explicit LiftoffAssembler(Zone*,
+ std::unique_ptr<AssemblerBuffer>);
+ V8_EXPORT_PRIVATE ~LiftoffAssembler() override;
Zone* zone() const { return cache_state_.stack_state.get_allocator().zone(); }
diff --git a/deps/v8/src/wasm/baseline/liftoff-compiler.cc b/deps/v8/src/wasm/baseline/liftoff-compiler.cc
index 324a3570b97..8c8c46a4670 100644
--- a/deps/v8/src/wasm/baseline/liftoff-compiler.cc
+++ b/deps/v8/src/wasm/baseline/liftoff-compiler.cc
@@ -6668,47 +6668,14 @@ class LiftoffCompiler {
void AtomicWait(FullDecoder* decoder, ValueKind kind,
const MemoryAccessImmediate& imm) {
- ValueKind index_kind;
{
LiftoffRegList pinned;
LiftoffRegister full_index = __ PeekToRegister(2, pinned);
- Register index_reg =
- BoundsCheckMem(decoder, imm.memory, value_kind_size(kind), imm.offset,
- full_index, pinned, kDoForceCheck, kCheckAlignment);
- pinned.set(index_reg);
-
- uintptr_t offset = imm.offset;
- Register index_plus_offset = index_reg;
-
- if (__ cache_state()->is_used(LiftoffRegister(index_reg))) {
- index_plus_offset =
- pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
- __ Move(index_plus_offset, index_reg, kIntPtrKind);
- }
- if (offset) {
- __ emit_ptrsize_addi(index_plus_offset, index_plus_offset, offset);
- }
-
- VarState& index = __ cache_state()->stack_state.end()[-3];
-
- // We replace the index on the value stack with the `index_plus_offset`
- // calculated above. Thereby the BigInt allocation below does not
- // overwrite the calculated value by accident.
- // The kind of `index_plus_offset has to be the same or smaller than the
- // original kind of `index`. The kind of index is kI32 for memory32, and
- // kI64 for memory64. On 64-bit platforms we can use in both cases the
- // kind of `index` also for `index_plus_offset`. Note that
- // `index_plus_offset` fits into a kI32 because we do a bounds check
- // first.
- // On 32-bit platforms, we have to use an kI32 also for memory64, because
- // `index_plus_offset` does not exist in a register pair.
- __ cache_state()->inc_used(LiftoffRegister(index_plus_offset));
- if (index.is_reg()) __ cache_state()->dec_used(index.reg());
- index_kind = index.kind() == kI32 ? kI32 : kIntPtrKind;
-
- index = VarState{index_kind, LiftoffRegister{index_plus_offset},
- index.offset()};
+ // Execute bounds and alignment checks upfront to preserve Wasm traps
+ // without modifying the value stack before any BigInt conversion.
+ BoundsCheckMem(decoder, imm.memory, value_kind_size(kind), imm.offset,
+ full_index, pinned, kDoForceCheck, kCheckAlignment);
}
{
// Convert the top value of the stack (the timeout) from I64 to a BigInt,
@@ -6737,18 +6704,41 @@ class LiftoffCompiler {
}
ValueKind expected_kind = kind == kI32 ? kI32 : kRef;
+ // Compute index + offset into a fresh pointer-sized register after BigInt
+ // conversions. For memory32, zero-extend to uintptr to prevent 64-bit
+ // sign-extension of >=2GiB offsets.
+ LiftoffRegList pinned{expected};
+ LiftoffRegister index = pinned.set(__ PeekToRegister(2, pinned));
+
+ Register index_plus_offset = no_reg;
+ if (imm.memory->is_memory64()) {
+ DCHECK_IMPLIES(kNeedI64RegPair, index.is_gp_pair());
+ // On 32-bit platforms, BoundsCheckMem already trapped if the high word of
+ // the 64-bit index was non-zero. The index fits in pointer size.
+ Register index_ptrsize = kNeedI64RegPair ? index.low_gp() : index.gp();
+ if (imm.offset) {
+ index_plus_offset =
+ pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
+ __ emit_ptrsize_addi(index_plus_offset, index_ptrsize, imm.offset);
+ } else {
+ index_plus_offset = index_ptrsize;
+ }
+ } else {
+ index_plus_offset = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
+ __ emit_u32_to_uintptr(index_plus_offset, index.gp());
+ if (imm.offset) {
+ __ emit_ptrsize_addi(index_plus_offset, index_plus_offset, imm.offset);
+ }
+ }
+
VarState timeout = __ cache_state()->stack_state.end()[-1];
- VarState index = __ cache_state()->stack_state.end()[-3];
- auto target = kind == kI32 ? Builtin::kWasmI32AtomicWait
- : Builtin::kWasmI64AtomicWait;
+ Builtin target = kind == kI32 ? Builtin::kWasmI32AtomicWait
+ : Builtin::kWasmI64AtomicWait;
- // The type of {index} can either by i32 or intptr, depending on whether
- // memory32 or memory64 is used. This is okay because both values get passed
- // by register.
- CallBuiltin(target, MakeSig::Params(kI32, index_kind, expected_kind, kRef),
+ CallBuiltin(target, MakeSig::Params(kI32, kIntPtrKind, expected_kind, kRef),
{{kI32, static_cast<int32_t>(imm.mem_index), 0},
- index,
+ {kIntPtrKind, LiftoffRegister{index_plus_offset}, 0},
{expected_kind, LiftoffRegister{expected}, 0},
timeout},
decoder->position());
@@ -7158,8 +7148,10 @@ class LiftoffCompiler {
void StructWait(FullDecoder* decoder, const Value& /* struct_obj */,
const FieldImmediate& imm, const Value& /* waitqueue */,
- const Value& /* expected_value */,
+ const Value& expected_value_arg,
const Value& /* timeout_ns */, Value* /* result */) {
+ ValueKind kind = expected_value_arg.type.kind();
+ DCHECK(kind == kI32 || kind == kI64 || is_reference(kind));
VarState timeout_ns_i64 = __ PopVarState();
// Convert the timeout from I64 to a BigInt.
@@ -7168,21 +7160,112 @@ class LiftoffCompiler {
MakeSig::Returns(kRef).Params(kI64), {timeout_ns_i64},
decoder->position());
- // We need to pop these three values after the previous builtin call,
+ VarState timeout{kRef, LiftoffRegister{kReturnRegister0}, 0};
+ VarState expected_value = __ cache_state() -> stack_state.back();
+ if (kind == kI64) {
+ // Put the timeout BigInt on the value stack so that it gets preserved
+ // across a potential GC triggered by the BigInt allocation below.
+ __ PushRegister(kRef, LiftoffRegister{kReturnRegister0});
+ CallBuiltin(
+ kNeedI64RegPair ? Builtin::kI32PairToBigInt : Builtin::kI64ToBigInt,
+ MakeSig::Returns(kRef).Params(kI64), {expected_value},
+ decoder->position());
+ timeout = __ PopVarState();
+ // Replace untagged expected_value with allocated BigInt:
+ __ DropValues(1);
+ expected_value = VarState{kRef, LiftoffRegister{kReturnRegister0}, 0};
+ } else {
+ expected_value = __ PopVarState();
+ }
+
+ // We need to pop these values after the previous builtin call(s),
// because register VarStates will get spilled and registers will be
- // overwritten by it.
- VarState expected_value = __ PopVarState();
+ // overwritten by them.
VarState waitqueue = __ PopVarState();
VarState struct_obj = __ PopVarState();
int offset = WasmStruct::kHeaderSize +
imm.struct_imm.struct_type->field_offset(imm.field_imm.index);
+ Builtin target = kind == kI32 ? Builtin::kWasmManagedObjectWait32
+ : kind == kI64 ? Builtin::kWasmManagedObjectWait64
+ : Builtin::kWasmManagedObjectWaitRef;
+ ValueKind expected_kind = kind == kI32 ? kI32 : kRef;
// Null check happens within the builtin.
CallBuiltin(
- Builtin::kWasmManagedObjectWait,
- MakeSig::Params(kRef, kI32, kI32, kRef, kRef).Returns(kI32),
+ target,
+ MakeSig::Params(kRef, kI32, expected_kind, kRef, kRef).Returns(kI32),
{struct_obj, VarState{kI32, offset, 0}, expected_value, waitqueue,
- VarState{kRef, LiftoffRegister{kReturnRegister0}, 0}},
+ timeout},
+ decoder->position());
+ __ PushRegister(kI32, LiftoffRegister{kReturnRegister0});
+ MaybeOSR();
+ }
+
+ void ArrayWait(FullDecoder* decoder, const Value& array_obj,
+ const ArrayIndexImmediate& /* imm */,
+ const Value& /* waitqueue */, const Value& /* index */,
+ const Value& expected_value_arg, const Value& /* timeout_ns */,
+ Value* /* result */) {
+ ValueKind kind = expected_value_arg.type.kind();
+ DCHECK(kind == kI32 || kind == kI64 || is_reference(kind));
+ VarState timeout_ns_i64 = __ PopVarState();
+
+ // Convert the timeout from I64 to a BigInt.
+ CallBuiltin(
+ kNeedI64RegPair ? Builtin::kI32PairToBigInt : Builtin::kI64ToBigInt,
+ MakeSig::Returns(kRef).Params(kI64), {timeout_ns_i64},
+ decoder->position());
+
+ VarState timeout{kRef, LiftoffRegister{kReturnRegister0}, 0};
+ VarState expected_value = __ cache_state() -> stack_state.back();
+ if (kind == kI64) {
+ // Put the timeout BigInt on the value stack so that it gets preserved
+ // across a potential GC triggered by the BigInt allocation below.
+ __ PushRegister(kRef, LiftoffRegister{kReturnRegister0});
+ CallBuiltin(
+ kNeedI64RegPair ? Builtin::kI32PairToBigInt : Builtin::kI64ToBigInt,
+ MakeSig::Returns(kRef).Params(kI64), {expected_value},
+ decoder->position());
+ timeout = __ PopVarState();
+ // Replace untagged expected_value with allocated BigInt:
+ __ DropValues(1);
+ expected_value = VarState{kRef, LiftoffRegister{kReturnRegister0}, 0};
+ } else {
+ expected_value = __ PopVarState();
+ }
+
+ // We need to pop these values after the previous builtin call(s),
+ // because register VarStates will get spilled and registers will be
+ // overwritten by them.
+ LiftoffRegList pinned{kReturnRegister0};
+ LiftoffRegister index = pinned.set(__ PopToModifiableRegister(pinned));
+ VarState waitqueue = __ PopVarState();
+ if (waitqueue.is_reg()) pinned.set(waitqueue.reg());
+ LiftoffRegister array = pinned.set(__ PopToRegister(pinned));
+
+ if (null_check_strategy_ == compiler::NullCheckStrategy::kExplicit) {
+ MaybeEmitNullCheck(decoder, array.gp(), pinned, array_obj.type);
+ }
+ bool implicit_null_check =
+ array_obj.type.is_nullable() &&
+ null_check_strategy_ == compiler::NullCheckStrategy::kTrapHandler;
+ BoundsCheckArray(decoder, implicit_null_check, array, index, pinned);
+
+ int elem_size_shift = value_kind_size_log2(kind);
+ DCHECK_NE(elem_size_shift, 0);
+ __ emit_i32_shli(index.gp(), index.gp(), elem_size_shift);
+ __ emit_i32_addi(index.gp(), index.gp(), WasmArray::kHeaderSize);
+
+ Builtin target = kind == kI32 ? Builtin::kWasmManagedObjectWait32
+ : kind == kI64 ? Builtin::kWasmManagedObjectWait64
+ : Builtin::kWasmManagedObjectWaitRef;
+ ValueKind expected_kind = kind == kI32 ? kI32 : kRef;
+ // Waitqueue null check happens within the builtin.
+ CallBuiltin(
+ target,
+ MakeSig::Params(kRef, kI32, expected_kind, kRef, kRef).Returns(kI32),
+ {VarState{kRef, array, 0}, VarState{kI32, index, 0}, expected_value,
+ waitqueue, timeout},
decoder->position());
__ PushRegister(kI32, LiftoffRegister{kReturnRegister0});
MaybeOSR();
diff --git a/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv-inl.h b/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv-inl.h
index ec8bff5ec2c..fb42204b277 100644
--- a/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv-inl.h
+++ b/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv-inl.h
@@ -2475,7 +2475,9 @@ void LiftoffAssembler::RecordSpillsInSafepoint(
SafepointTableBuilder::Safepoint& safepoint, LiftoffRegList all_spills,
LiftoffRegList ref_spills, int spill_offset) {
LiftoffRegList fp_spills = all_spills & kFpCacheRegList;
- int spill_space_size = fp_spills.GetNumRegsSet() * kSimd128Size;
+ int spill_space_size = fp_spills.GetNumRegsSet() * kStackSlotSize;
+ LiftoffRegList simd_spills = all_spills & kSimd128CacheRegList;
+ spill_space_size += simd_spills.GetNumRegsSet() * kSimd128Size;
LiftoffRegList gp_spills = all_spills & kGpCacheRegList;
while (!gp_spills.is_empty()) {
LiftoffRegister reg = gp_spills.GetFirstRegSet();
diff --git a/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64-inl.h b/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64-inl.h
index 326e73790d2..73310799176 100644
--- a/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64-inl.h
+++ b/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64-inl.h
@@ -230,7 +230,9 @@ void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
}
void LiftoffAssembler::AlignFrameSize() {
- max_used_spill_offset_ = RoundUp(max_used_spill_offset_, kSystemPointerSize);
+ int alignment = v8_flags.enforce_x64_16byte_alignment ? 2 * kSystemPointerSize
+ : kSystemPointerSize;
+ max_used_spill_offset_ = RoundUp(max_used_spill_offset_, alignment);
}
void LiftoffAssembler::PatchPrepareStackFrame(
@@ -245,6 +247,8 @@ void LiftoffAssembler::PatchPrepareStackFrame(
frame_size -= kSystemPointerSize;
}
DCHECK_EQ(0, frame_size % kSystemPointerSize);
+ DCHECK_IMPLIES(v8_flags.enforce_x64_16byte_alignment,
+ GetTotalFrameSize() % (2 * kSystemPointerSize) == 0);
// We can't run out of space when patching, just pass anything big enough to
// not cause the assembler to try to grow the buffer.
@@ -649,8 +653,15 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
break;
case LoadType::kF32LoadF16: {
CpuFeatureScope f16c_scope(this, F16C);
- CpuFeatureScope avx2_scope(this, AVX2);
- vpbroadcastw(dst.fp(), src_op);
+ if (CpuFeatures::IsSupported(AVX2)) {
+ CpuFeatureScope avx2_scope(this, AVX2);
+ vpbroadcastw(dst.fp(), src_op);
+ } else {
+ CpuFeatureScope avx_scope(this, AVX);
+ vxorps(dst.fp(), dst.fp(), dst.fp());
+ if (trapping_load_pc) *trapping_load_pc = pc_offset();
+ vpinsrw(dst.fp(), dst.fp(), src_op, 0);
+ }
vcvtph2ps(dst.fp(), dst.fp());
break;
}
@@ -5090,7 +5101,7 @@ bool LiftoffAssembler::emit_f16x8_qfms(LiftoffRegister dst,
}
bool LiftoffAssembler::supports_f16_mem_access() {
- return CpuFeatures::IsSupported(F16C) && CpuFeatures::IsSupported(AVX2);
+ return CpuFeatures::IsSupported(F16C);
}
void LiftoffAssembler::set_trap_on_oob_mem64(Register index, uint64_t max_index,
diff --git a/deps/v8/src/wasm/constant-expression-interface.cc b/deps/v8/src/wasm/constant-expression-interface.cc
index 4451c93795c..c6f0e51196f 100644
--- a/deps/v8/src/wasm/constant-expression-interface.cc
+++ b/deps/v8/src/wasm/constant-expression-interface.cc
@@ -194,7 +194,6 @@ void ConstantExpressionInterface::StructNew(FullDecoder* decoder,
if (!generate_value()) return;
const TypeDefinition& type = module_->type(imm.index);
- SharedObjectConditionalSafePublishGuard publish_guard(type.is_shared);
const StructType* struct_type = type.struct_type;
DCHECK_EQ(struct_type, imm.struct_type);
@@ -217,18 +216,18 @@ void ConstantExpressionInterface::StructNew(FullDecoder* decoder,
struct_type, rtt,
type.is_shared ? AllocationType::kSharedOld : AllocationType::kOld);
}
- {
- DisallowGarbageCollection no_gc; // Must initialize fields first.
-
- for (uint32_t i = 0; i < struct_type->field_count(); i++) {
- int offset = struct_type->field_offset(i);
- if (struct_type->field(i).is_numeric()) {
- uint8_t* address =
- reinterpret_cast<uint8_t*>(obj->RawFieldAddress(offset));
- args[i].runtime_value.Packed(struct_type->field(i)).CopyTo(address);
- } else {
- obj->SetTaggedFieldValue(offset, *args[i].runtime_value.to_ref());
- }
+
+ DisallowGarbageCollection no_gc; // Must initialize fields first.
+ SharedObjectConditionalSafePublishGuard publish_guard(*obj, type.is_shared);
+
+ for (uint32_t i = 0; i < struct_type->field_count(); i++) {
+ int offset = struct_type->field_offset(i);
+ if (struct_type->field(i).is_numeric()) {
+ uint8_t* address =
+ reinterpret_cast<uint8_t*>(obj->RawFieldAddress(offset));
+ args[i].runtime_value.Packed(struct_type->field(i)).CopyTo(address);
+ } else {
+ obj->SetTaggedFieldValue(offset, *args[i].runtime_value.to_ref());
}
}
@@ -303,7 +302,6 @@ void ConstantExpressionInterface::StructNewDefault(
if (!generate_value()) return;
const TypeDefinition& type = module_->type(imm.index);
- SharedObjectConditionalSafePublishGuard publish_guard(type.is_shared);
const StructType* struct_type = type.struct_type;
DCHECK_EQ(struct_type, imm.struct_type);
@@ -324,24 +322,23 @@ void ConstantExpressionInterface::StructNewDefault(
type.is_shared ? AllocationType::kSharedOld : AllocationType::kOld);
}
- {
- DisallowGarbageCollection no_gc; // Must initialize fields first.
-
- for (uint32_t i = 0; i < struct_type->field_count(); i++) {
- int offset = struct_type->field_offset(i);
- ValueType ftype = struct_type->field(i);
- if (ftype.is_numeric()) {
- uint8_t* address =
- reinterpret_cast<uint8_t*>(obj->RawFieldAddress(offset));
- DefaultValueForType(ftype, isolate_, module_)
- .Packed(ftype)
- .CopyTo(address);
- } else {
- // No write barrier needed, as read-only-space objects never move.
- TaggedField<Object, WasmStruct::kHeaderSize>::store(
- *obj, offset,
- *DefaultValueForType(ftype, isolate_, module_).to_ref());
- }
+ DisallowGarbageCollection no_gc; // Must initialize fields first.
+ SharedObjectConditionalSafePublishGuard publish_guard(*obj, type.is_shared);
+
+ for (uint32_t i = 0; i < struct_type->field_count(); i++) {
+ int offset = struct_type->field_offset(i);
+ ValueType ftype = struct_type->field(i);
+ if (ftype.is_numeric()) {
+ uint8_t* address =
+ reinterpret_cast<uint8_t*>(obj->RawFieldAddress(offset));
+ DefaultValueForType(ftype, isolate_, module_)
+ .Packed(ftype)
+ .CopyTo(address);
+ } else {
+ // No write barrier needed, as read-only-space objects never move.
+ TaggedField<Object, WasmStruct::kHeaderSize>::store(
+ *obj, offset,
+ *DefaultValueForType(ftype, isolate_, module_).to_ref());
}
}
@@ -376,7 +373,6 @@ void ConstantExpressionInterface::ArrayNewDefault(
void ConstantExpressionInterface::ArrayNewImpl(
FullDecoder* decoder, const ArrayIndexImmediate& imm, const Value& length,
const Value& initial_value, Value* result, WriteBarrierMode write_barrier) {
- SharedObjectConditionalSafePublishGuard publish_guard(imm.shared);
DirectHandle<Map> rtt{
Cast<Map>(
trusted_instance_data_->managed_object_maps()->get(imm.index.index)),
@@ -388,10 +384,13 @@ void ConstantExpressionInterface::ArrayNewImpl(
}
AllocationType allocation =
imm.shared ? AllocationType::kSharedOld : AllocationType::kOld;
+
+ DirectHandle<WasmArray> obj = isolate_->factory()->NewWasmArray(
+ imm.array_type->element_type(), length.runtime_value.to_u32(),
+ initial_value.runtime_value, rtt, allocation, write_barrier);
+
result->runtime_value = WasmValue(
- isolate_->factory()->NewWasmArray(
- imm.array_type->element_type(), length.runtime_value.to_u32(),
- initial_value.runtime_value, rtt, allocation, write_barrier),
+ obj,
decoder->module_->canonical_type(
ValueType::Ref(imm.heap_type()).AsExactIfEnabled(decoder->enabled_)));
}
@@ -400,7 +399,6 @@ void ConstantExpressionInterface::ArrayNewFixed(
FullDecoder* decoder, const ArrayIndexImmediate& array_imm,
const IndexImmediate& length_imm, const Value elements[], Value* result) {
if (!generate_value()) return;
- SharedObjectConditionalSafePublishGuard publish_guard(array_imm.shared);
DirectHandle<Map> rtt{
Cast<Map>(trusted_instance_data_->managed_object_maps()->get(
array_imm.index.index)),
@@ -412,12 +410,14 @@ void ConstantExpressionInterface::ArrayNewFixed(
}
AllocationType allocation =
array_imm.shared ? AllocationType::kSharedOld : AllocationType::kOld;
+
+ DirectHandle<WasmArray> obj = isolate_->factory()->NewWasmArrayFromElements(
+ array_imm.array_type, element_values, rtt, allocation);
+ SharedObjectConditionalSafePublishGuard publish_guard(*obj, array_imm.shared);
result->runtime_value =
- WasmValue(isolate_->factory()->NewWasmArrayFromElements(
- array_imm.array_type, element_values, rtt, allocation),
- decoder->module_->canonical_type(
- ValueType::Ref(array_imm.heap_type())
- .AsExactIfEnabled(decoder->enabled_)));
+ WasmValue(obj, decoder->module_->canonical_type(
+ ValueType::Ref(array_imm.heap_type())
+ .AsExactIfEnabled(decoder->enabled_)));
}
// TODO(14034): These expressions are non-constant for now. There are plans to
@@ -429,7 +429,6 @@ void ConstantExpressionInterface::ArrayNewSegment(
const Value& length_value, Value* result) {
if (!generate_value()) return;
- SharedObjectConditionalSafePublishGuard publish_guard(array_imm.shared);
DirectHandle<Map> rtt{
Cast<Map>(trusted_instance_data_->managed_object_maps()->get(
array_imm.index.index)),
@@ -465,6 +464,8 @@ void ConstantExpressionInterface::ArrayNewSegment(
DirectHandle<WasmArray> array_value =
isolate_->factory()->NewWasmArrayFromMemory(length, rtt, allocation,
element_type, source);
+ SharedObjectConditionalSafePublishGuard publish_guard(*array_value,
+ array_imm.shared);
result->runtime_value = WasmValue(array_value, result_type);
} else {
const wasm::WasmElemSegment* elem_segment =
@@ -489,6 +490,8 @@ void ConstantExpressionInterface::ArrayNewSegment(
// A smi result stands for an error code.
error_ = static_cast<MessageTemplate>(Cast<Smi>(*array_object).value());
} else {
+ SharedObjectConditionalSafePublishGuard publish_guard(
+ Cast<WasmArray>(*array_object), array_imm.shared);
result->runtime_value = WasmValue(array_object, result_type);
}
}
diff --git a/deps/v8/src/wasm/function-body-decoder-impl.h b/deps/v8/src/wasm/function-body-decoder-impl.h
index 284bed29c55..3818b05ab2c 100644
--- a/deps/v8/src/wasm/function-body-decoder-impl.h
+++ b/deps/v8/src/wasm/function-body-decoder-impl.h
@@ -1603,6 +1603,9 @@ struct ControlBase : public PcForErrors<ValidationTag::validate> {
F(StructWait, const Value& struct_obj, const FieldImmediate& imm, \
const Value& waitqueue, const Value& expected_value, \
const Value& timeout_ns, Value* result) \
+ F(ArrayWait, const Value& array_obj, const ArrayIndexImmediate& imm, \
+ const Value& waitqueue, const Value& index, const Value& expected_value, \
+ const Value& timeout_ns, Value* result) \
F(WaitqueueNotify, const Value& waitqueue, const Value& max_waiters, \
Value* result) \
F(ArrayGet, const Value& array_obj, const ArrayIndexImmediate& imm, \
@@ -2845,6 +2848,11 @@ class WasmDecoder : public Decoder {
(ios.Field(field), ...);
return length + field.length;
}
+ case kExprArrayWait: {
+ ArrayIndexImmediate array(decoder, pc + length, validate);
+ (ios.TypeIndex(array), ...);
+ return length + array.length;
+ }
case kExprArrayAtomicGet:
case kExprArrayAtomicGetS:
case kExprArrayAtomicGetU:
@@ -7410,7 +7418,6 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
return opcode_length + field.length + memory_order.length;
}
case kExprStructWait: {
- // TODO(475455008): Implement other field types.
CHECK_PROTOTYPE_OPCODE(shared);
NON_CONST_ONLY
FieldImmediate field(this, this->pc_ + opcode_length, validate);
@@ -7419,24 +7426,62 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
}
const StructType* struct_type = field.struct_imm.struct_type;
ValueType field_type = struct_type->field(field.field_imm.index);
- if (field_type != kWasmI32) {
+ if (!VALIDATE(field_type == kWasmI32 || field_type == kWasmI64 ||
+ IsSubtypeOf(field_type.AsNonShared(), kWasmEqRef,
+ this->module_))) {
this->DecodeError(
- "%s: Field %d of type %d must be of type i32, found %s "
- "instead",
+ "%s: Field %d of type %d must be of type i32, i64, or subtype "
+ "of eqref, found %s instead",
WasmOpcodes::OpcodeName(opcode), field.struct_imm.index,
field.field_imm.index, field_type.name().c_str());
return 0;
}
+ ValueType expected_type =
+ field_type.is_ref()
+ ? (field_type.is_shared() ? kWasmSharedEqRef : kWasmEqRef)
+ : field_type;
auto [struct_obj, waitqueue, expected_value, timeout_ns] =
Pop(ValueType::RefNull(field.struct_imm.heap_type()),
- kWasmWaitqueueRef, kWasmI32, kWasmI64);
+ kWasmWaitqueueRef, expected_type, kWasmI64);
Value* result = Push(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StructWait, struct_obj, field,
waitqueue, expected_value,
timeout_ns, result);
return opcode_length + field.length;
}
+ case kExprArrayWait: {
+ CHECK_PROTOTYPE_OPCODE(shared);
+ NON_CONST_ONLY
+ ArrayIndexImmediate imm(this, this->pc_ + opcode_length, validate);
+ if (!this->Validate(this->pc_ + opcode_length, imm)) {
+ return 0;
+ }
+ ValueType element_type = imm.array_type->element_type();
+ if (!VALIDATE(element_type == kWasmI32 || element_type == kWasmI64 ||
+ IsSubtypeOf(element_type.AsNonShared(), kWasmEqRef,
+ this->module_))) {
+ this->DecodeError(
+ "%s: Array type %d must have element type i32, i64, or subtype "
+ "of eqref, found %s instead",
+ WasmOpcodes::OpcodeName(opcode), imm.index.index,
+ element_type.name().c_str());
+ return 0;
+ }
+
+ ValueType expected_type =
+ element_type.is_ref()
+ ? (element_type.is_shared() ? kWasmSharedEqRef : kWasmEqRef)
+ : element_type;
+ auto [array_obj, waitqueue, index, expected_value, timeout_ns] =
+ Pop(ValueType::RefNull(imm.heap_type()), kWasmWaitqueueRef,
+ kWasmI32, expected_type, kWasmI64);
+ Value* result = Push(kWasmI32);
+ CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayWait, array_obj, imm, waitqueue,
+ index, expected_value, timeout_ns,
+ result);
+ return opcode_length + imm.length;
+ }
case kExprWaitqueueNotify: {
CHECK_PROTOTYPE_OPCODE(shared);
NON_CONST_ONLY
diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc
index 2de1e3f956b..e5259b9a92e 100644
--- a/deps/v8/src/wasm/module-compiler.cc
+++ b/deps/v8/src/wasm/module-compiler.cc
@@ -8,6 +8,7 @@
#include <atomic>
#include <memory>
#include <queue>
+#include <string_view>
#include "src/api/api-inl.h"
#include "src/base/enum-set.h"
@@ -1612,6 +1613,7 @@ void PublishDetectedFeatures(WasmDetectedFeatures detected_features,
{WasmDetectedFeature::sign_extension_ops, Feature::kWasmSignExtensionOps},
{WasmDetectedFeature::custom_descriptors,
Feature::kWasmCustomDescriptors},
+ {WasmDetectedFeature::wide_arithmetic, Feature::kWasmWideArithmetic},
};
// Check that every staging or shipping feature has a use counter as that is
@@ -2464,6 +2466,10 @@ class AsyncStreamingProcessor final : public StreamingProcessor {
private:
void CommitCompilationUnits();
+ // Sets a crash key ("v8-wasm-streaming-error") with the first encountered
+ // failure to help diagnose unexpected streaming compilation errors (see
+ // issue 455046584). Must be called on the main thread.
+ void SetCrashKey(std::string_view message);
ModuleDecoder decoder_;
AsyncCompileJob* job_;
@@ -2471,6 +2477,7 @@ class AsyncStreamingProcessor final : public StreamingProcessor {
int num_functions_ = 0;
bool prefix_cache_hit_ = false;
bool before_code_section_ = true;
+ bool has_error_ = false;
ValidateFunctionsStreamingJobData validate_functions_job_data_;
std::unique_ptr<JobHandle> validate_functions_job_handle_;
@@ -2567,7 +2574,7 @@ void AsyncCompileJob::FinishCompile(
stream_ ? base::VectorOf(stream_->url()) : base::Vector<const char>();
auto script =
GetWasmEngine()->GetOrCreateScript(isolate, native_module, source_url);
- module_object = WasmModuleObject::New(isolate, native_module, script);
+ module_object = WasmModuleObject::New(isolate, script);
}
// We should only get here if compilation succeeded.
@@ -2621,10 +2628,10 @@ void AsyncCompileJob::FinishCompile(
// Finish the wasm script now and make it public to the debugger.
DirectHandle<Script> script(module_object->script(), isolate);
+ DCHECK_EQ(script->type(), Script::Type::kWasm);
auto sourcemap_symbol =
module->debug_symbols[WasmDebugSymbols::Type::SourceMap];
- if (script->type() == Script::Type::kWasm &&
- sourcemap_symbol.type != WasmDebugSymbols::Type::None &&
+ if (sourcemap_symbol.type != WasmDebugSymbols::Type::None &&
!sourcemap_symbol.external_url.is_empty()) {
ModuleWireBytes wire_bytes(native_module->wire_bytes());
MaybeDirectHandle<String> src_map_str =
@@ -3170,12 +3177,33 @@ void AsyncStreamingProcessor::OnFinishedChunk() {
if (compilation_unit_builder_) CommitCompilationUnits();
}
+void AsyncStreamingProcessor::SetCrashKey(std::string_view message) {
+ if (has_error_) return;
+ has_error_ = true;
+ Isolate* isolate = job_->isolate_specific_info_.isolate_;
+ if (isolate && isolate->HasCrashKeyStringCallbacks()) {
+ // Crash keys allocated via the embedder callback are process-wide and never
+ // freed, and in Chromium the callbacks are only installed on the main
+ // thread's Isolate, so caching the key in a process-wide static is safe.
+ static v8::CrashKey crash_key = isolate->AllocateCrashKeyString(
+ "v8-wasm-streaming-error", v8::CrashKeySize::Size1024);
+ isolate->SetCrashKeyString(crash_key, message);
+ }
+}
+
// Finish the processing of the stream.
void AsyncStreamingProcessor::OnFinishedStream(
base::OwnedVector<const uint8_t> bytes, bool after_error) {
TRACE_STREAMING("Finish stream...\n");
ModuleResult module_result = decoder_.FinishDecoding();
- if (module_result.failed()) after_error = true;
+ if (module_result.failed()) {
+ SetCrashKey("ModuleDecoder: " + module_result.error().message());
+ after_error = true;
+ } else if (after_error) {
+ // `after_error` was passed in as true from StreamingDecoder, but
+ // ModuleDecoder did not fail (e.g. unexpected EOF or varint error).
+ SetCrashKey("StreamingDecoder failed");
+ }
if (validate_functions_job_handle_) {
// Wait for background validation to finish, then check if a validation
@@ -3184,7 +3212,10 @@ void AsyncStreamingProcessor::OnFinishedStream(
// instead.
validate_functions_job_handle_->Join();
validate_functions_job_handle_.reset();
- if (validate_functions_job_data_.found_error) after_error = true;
+ if (validate_functions_job_data_.found_error) {
+ SetCrashKey("FunctionValidation failed");
+ after_error = true;
+ }
job_->detected_features_ |=
validate_functions_job_data_.detected_features.load(
std::memory_order_relaxed);
@@ -3200,6 +3231,7 @@ void AsyncStreamingProcessor::OnFinishedStream(
if (WasmError error = ValidateAndSetBuiltinImports(
module_result.value().get(), job_->wire_bytes_.module_bytes(),
job_->compile_imports_, &detected_imports_features)) {
+ SetCrashKey("ValidateBuiltinImports: " + error.message());
after_error = true;
} else {
job_->detected_features_ |= detected_imports_features;
@@ -3320,6 +3352,7 @@ void AsyncStreamingProcessor::OnFinishedStream(
// We finally call {Failed} or {FinishCompile}, which will invalidate the
// {AsyncCompileJob} and delete {this}.
if (failed) {
+ SetCrashKey("CompilationState failed");
std::move(*job_).Failed();
return;
}
diff --git a/deps/v8/src/wasm/turboshaft-graph-interface.cc b/deps/v8/src/wasm/turboshaft-graph-interface.cc
index a186831fcbc..1fef1399ee8 100644
--- a/deps/v8/src/wasm/turboshaft-graph-interface.cc
+++ b/deps/v8/src/wasm/turboshaft-graph-interface.cc
@@ -2130,9 +2130,11 @@ class TurboshaftGraphBuildingInterface
offsetof(WasmFastApiCallData, callback_data_));
V<WordPtr> data_argument_to_pass = __ AdaptLocalArgument(callback_data);
+ START_ALLOW_USE_DEPRECATED()
+ constexpr size_t data_offset = offsetof(v8::FastApiCallbackOptions, data);
+ END_ALLOW_USE_DEPRECATED()
__ StoreOffHeap(options_object, data_argument_to_pass,
- MemoryRepresentation::UintPtr(),
- offsetof(v8::FastApiCallbackOptions, data));
+ MemoryRepresentation::UintPtr(), data_offset);
}
inputs[param_count] = options_object;
@@ -3910,7 +3912,7 @@ class TurboshaftGraphBuildingInterface
BIND(if_catch, caught_exception);
// The first unpacked value is the exception itself in the case of a JS
// exception.
- values[0].op = caught_exception;
+ values[0].op = __ AnnotateWasmType(caught_exception, values[0].type);
} else {
TSBlock* if_catch = __ NewBlock();
__ Branch(ConditionWithHint(__ TaggedEqual(caught_tag, expected_tag)),
@@ -3982,7 +3984,8 @@ class TurboshaftGraphBuildingInterface
if (catch_case.kind == kCatchAll || catch_case.kind == kCatchAllRef) {
if (catch_case.kind == kCatchAllRef) {
DCHECK_EQ(values.size(), 1);
- values.last().op = block->exception;
+ values.last().op =
+ __ AnnotateWasmType(block->exception, values.last().type);
}
BrOrRet(decoder, catch_case.br_imm.depth);
return;
@@ -4036,7 +4039,6 @@ class TurboshaftGraphBuildingInterface
if (catch_case.kind == kCatchRef) {
UnpackWasmException(decoder, block->exception,
values.SubVector(0, values.size() - 1));
- values.last().op = block->exception;
} else {
UnpackWasmException(decoder, block->exception, values);
}
@@ -4051,7 +4053,11 @@ class TurboshaftGraphBuildingInterface
BIND(if_catch, caught_exception);
// The first unpacked value is the exception itself in the case of a JS
// exception.
- values[0].op = caught_exception;
+ values[0].op = __ AnnotateWasmType(caught_exception, values[0].type);
+ if (catch_case.kind == kCatchRef) {
+ values.last().op =
+ __ AnnotateWasmType(block->exception, values.last().type);
+ }
} else {
TSBlock* if_catch = __ NewBlock();
__ Branch(ConditionWithHint(__ TaggedEqual(caught_tag, expected_tag)),
@@ -4060,7 +4066,8 @@ class TurboshaftGraphBuildingInterface
if (catch_case.kind == kCatchRef) {
UnpackWasmException(decoder, block->exception,
values.SubVector(0, values.size() - 1));
- values.last().op = block->exception;
+ values.last().op =
+ __ AnnotateWasmType(block->exception, values.last().type);
} else {
UnpackWasmException(decoder, block->exception, values);
}
@@ -4278,11 +4285,13 @@ class TurboshaftGraphBuildingInterface
__ StoreOffHeap(arg_buffer, args[index].op,
MemoryRepresentationOffHeap(args[index].type), offset);
});
+ current_resume_handlers_ = asm_handlers;
asm_.set_effect_handlers_for_next_call(asm_handlers);
V<WordPtr> result_buffer =
CallBuiltinThroughJumptable<BuiltinCallDescriptor::WasmFXResume,
HandleEffects::kYes>(
decoder, {stack, arg_buffer}, CheckForException::kCatchInThisFrame);
+ asm_.clear_effect_handlers();
// Keep the continuation object alive to ensure that the external stack
// pointer is not freed prematurely.
__ Retain(V<Object>::Cast(cont_ref.op));
@@ -4291,12 +4300,12 @@ class TurboshaftGraphBuildingInterface
void ResumeHandler(FullDecoder* decoder, const HandlerCase& handler,
size_t handler_index, Value* cont_val, Value* tag_params) {
- __ Bind(asm_.effect_handlers_for_next_call()[handler_index].block);
+ __ Bind(current_resume_handlers_[handler_index].block);
// Reuse the "CatchBlockBegin" pseudo op to mark the beginning of an effect
// handler block. It works the same way but generates the continuation
// object instead of the exception.
- OpIndex cont = __ CatchBlockBegin();
- OpIndex arg_buffer = __ WasmFXArgBuffer();
+ V<Object> cont = __ CatchBlockBegin();
+ V<WordPtr> arg_buffer = __ WasmFXArgBuffer();
// Unpack tag params.
const FunctionSig* sig = handler.tag.tag->sig;
@@ -4311,7 +4320,7 @@ class TurboshaftGraphBuildingInterface
});
instance_cache_.ReloadCachedMemory();
- cont_val->op = cont;
+ cont_val->op = __ AnnotateWasmType(cont, cont_val->type);
DCHECK_EQ(kOnSuspend, handler.kind);
BrOrRet(decoder, handler.maybe_depth.br.depth);
}
@@ -4330,6 +4339,7 @@ class TurboshaftGraphBuildingInterface
TrustedFixedArray);
V<WasmExceptionTag> tag = V<WasmExceptionTag>::Cast(
__ LoadTrustedFixedArrayElement(instance_tags, exc_imm.index));
+ current_resume_handlers_ = asm_handlers;
asm_.set_effect_handlers_for_next_call(asm_handlers);
V<WordPtr> result_buffer =
CallBuiltinThroughJumptable<BuiltinCallDescriptor::WasmFXResumeThrow,
@@ -4337,6 +4347,7 @@ class TurboshaftGraphBuildingInterface
decoder,
{stack, tag, array, instance_cache_.trusted_instance_data()},
CheckForException::kCatchInThisFrame);
+ asm_.clear_effect_handlers();
// Keep the continuation object alive to ensure that the external stack
// pointer is not freed prematurely.
__ Retain(V<Object>::Cast(cont_ref.op));
@@ -4352,11 +4363,13 @@ class TurboshaftGraphBuildingInterface
Value returns[]) {
auto [stack, asm_handlers] =
PrepareResume(decoder, handlers, cont_ref, cont_imm);
+ current_resume_handlers_ = asm_handlers;
asm_.set_effect_handlers_for_next_call(asm_handlers);
V<WordPtr> result_buffer =
CallBuiltinThroughJumptable<BuiltinCallDescriptor::WasmFXResumeThrowRef,
HandleEffects::kYes>(
decoder, {stack, exn.op}, CheckForException::kCatchInThisFrame);
+ asm_.clear_effect_handlers();
// Keep the continuation object alive to ensure that the external stack
// pointer is not freed prematurely.
__ Retain(V<Object>::Cast(cont_ref.op));
@@ -4440,7 +4453,7 @@ class TurboshaftGraphBuildingInterface
}
void EndEffectHandlers(FullDecoder* decoder) {
- asm_.clear_effect_handlers();
+ current_resume_handlers_ = {};
__ Bind(resume_return_block_);
instance_cache_.ReloadCachedMemory();
}
@@ -5467,21 +5480,58 @@ class TurboshaftGraphBuildingInterface
memory_order);
}
+ void ManagedObjectWait(FullDecoder* decoder, const Value& object,
+ V<Word32> offset, const Value& waitqueue,
+ const Value& expected_value, const Value& timeout_ns,
+ Value* result) {
+ ValueKind kind = expected_value.type.kind();
+ DCHECK(kind == kI32 || kind == kI64 || is_reference(kind));
+ V<BigInt> timeout_bigint = BuildChangeInt64ToBigInt(
+ timeout_ns.get<Word64>(), StubCallMode::kCallWasmRuntimeStub);
+ // Null check happens within the builtin.
+ if (kind == kI32) {
+ result->op = CallBuiltinThroughJumptable<
+ BuiltinCallDescriptor::WasmManagedObjectWait32>(
+ decoder,
+ {object.op, offset, expected_value.op, waitqueue.op, timeout_bigint});
+ } else if (kind == kI64) {
+ V<BigInt> expected_bigint = BuildChangeInt64ToBigInt(
+ expected_value.get<Word64>(), StubCallMode::kCallWasmRuntimeStub);
+ result->op = CallBuiltinThroughJumptable<
+ BuiltinCallDescriptor::WasmManagedObjectWait64>(
+ decoder,
+ {object.op, offset, expected_bigint, waitqueue.op, timeout_bigint});
+ } else {
+ result->op = CallBuiltinThroughJumptable<
+ BuiltinCallDescriptor::WasmManagedObjectWaitRef>(
+ decoder,
+ {object.op, offset, expected_value.op, waitqueue.op, timeout_bigint});
+ }
+ }
+
void StructWait(FullDecoder* decoder, const Value& struct_obj,
const FieldImmediate& imm, const Value& waitqueue,
const Value& expected_value, const Value& timeout_ns,
Value* result) {
- // Null check happens within the builtin.
- result->op = CallBuiltinThroughJumptable<
- BuiltinCallDescriptor::WasmManagedObjectWait>(
- decoder,
- {struct_obj.op,
- __ Word32Constant(
- WasmStruct::kHeaderSize +
- imm.struct_imm.struct_type->field_offset(imm.field_imm.index)),
- expected_value.op, waitqueue.op,
- BuildChangeInt64ToBigInt(timeout_ns.get<Word64>(),
- StubCallMode::kCallWasmRuntimeStub)});
+ V<Word32> offset = __ Word32Constant(
+ WasmStruct::kHeaderSize +
+ imm.struct_imm.struct_type->field_offset(imm.field_imm.index));
+ ManagedObjectWait(decoder, struct_obj, offset, waitqueue, expected_value,
+ timeout_ns, result);
+ }
+
+ void ArrayWait(FullDecoder* decoder, const Value& array_obj,
+ const ArrayIndexImmediate& imm, const Value& waitqueue,
+ const Value& index, const Value& expected_value,
+ const Value& timeout_ns, Value* result) {
+ auto array_value = array_obj.get<WasmArrayNullable>();
+ __ WasmBoundsCheckArray(array_value, index.get<Word32>(), array_obj.type);
+ ValueKind kind = expected_value.type.kind();
+ V<Word32> offset = __ Word32Add(
+ __ Word32Constant(WasmArray::kHeaderSize),
+ __ Word32ShiftLeft(index.get<Word32>(), value_kind_size_log2(kind)));
+ ManagedObjectWait(decoder, array_obj, offset, waitqueue, expected_value,
+ timeout_ns, result);
}
void WaitqueueNotify(FullDecoder* decoder, const Value& waitqueue,
@@ -8975,7 +9025,9 @@ class TurboshaftGraphBuildingInterface
}
case kRef:
case kRefNull:
- value.op = __ LoadFixedArrayElement(exception_values_array, index);
+ value.op = __ AnnotateWasmType(
+ __ LoadFixedArrayElement(exception_values_array, index),
+ value.type);
index++;
break;
case kI8:
@@ -9112,7 +9164,8 @@ class TurboshaftGraphBuildingInterface
BuiltinCallDescriptor::WasmAllocateDescriptorStruct>(
decoder, {rtt, __ Word32Constant(imm.index.index), first_field});
struct_value = __ AnnotateWasmType(
- struct_value, ValueType::Ref(decoder->module_->heap_type(imm.index)));
+ struct_value,
+ ValueType::Ref(decoder->module_->heap_type(imm.index)).AsExact());
} else {
struct_value = __ WasmAllocateStruct(rtt, imm.struct_type, imm.index);
}
@@ -9681,6 +9734,10 @@ class TurboshaftGraphBuildingInterface
// Target block after returning normally from a resume. Saved temporarily here
// so that we can bind it later after generating the handler branches.
TSBlock* resume_return_block_ = nullptr;
+ // Handler blocks for the resume instruction currently being decoded. Saved
+ // temporarily here so that {ResumeHandler} can bind each handler block after
+ // the asm handlers have already been cleared.
+ base::Vector<compiler::turboshaft::EffectHandler> current_resume_handlers_;
// Manages code coverage instrumentation.
std::unique_ptr<WasmCoverageInstrumentation<FullDecoder>>
diff --git a/deps/v8/src/wasm/value-type.h b/deps/v8/src/wasm/value-type.h
index 49d0f6bb334..c65c55b2580 100644
--- a/deps/v8/src/wasm/value-type.h
+++ b/deps/v8/src/wasm/value-type.h
@@ -1167,6 +1167,8 @@ constexpr IndependentHeapType kWasmExnRef{GenericKind::kExn};
constexpr IndependentHeapType kWasmSharedExnRef{GenericKind::kExn, kNullable,
SharedFlag{true}};
constexpr IndependentHeapType kWasmEqRef{GenericKind::kEq};
+constexpr IndependentHeapType kWasmSharedEqRef{GenericKind::kEq, kNullable,
+ SharedFlag{true}};
constexpr IndependentHeapType kWasmI31Ref{GenericKind::kI31};
constexpr IndependentHeapType kWasmRefI31{GenericKind::kI31, kNonNullable};
constexpr IndependentHeapType kWasmStructRef{GenericKind::kStruct};
diff --git a/deps/v8/src/wasm/wasm-builtin-list.h b/deps/v8/src/wasm/wasm-builtin-list.h
index 620e7ddac1b..57b337bc8ca 100644
--- a/deps/v8/src/wasm/wasm-builtin-list.h
+++ b/deps/v8/src/wasm/wasm-builtin-list.h
@@ -115,7 +115,9 @@ namespace v8::internal::wasm {
V(WasmAllocateDescriptorStruct) \
V(WasmAllocateSharedStructWithRtt) \
V(WasmWaitqueueNew) \
- V(WasmManagedObjectWait) \
+ V(WasmManagedObjectWait32) \
+ V(WasmManagedObjectWait64) \
+ V(WasmManagedObjectWaitRef) \
V(WasmConfigureAllPrototypesOpt) \
V(WasmOnStackReplace) \
V(WasmReject) \
diff --git a/deps/v8/src/wasm/wasm-code-manager.cc b/deps/v8/src/wasm/wasm-code-manager.cc
index dbfcfa9ef3b..f3578610df7 100644
--- a/deps/v8/src/wasm/wasm-code-manager.cc
+++ b/deps/v8/src/wasm/wasm-code-manager.cc
@@ -348,11 +348,13 @@ void WasmCode::Validate() const {
std::numeric_limits<uint16_t>::max());
#ifdef DEBUG
+#ifdef ENABLE_SLOW_DCHECKS
NativeModule::CallIndirectTargetMap function_index_map;
if (native_module_) {
function_index_map =
native_module_->CreateIndirectCallTargetToFunctionIndexMap();
}
+#endif
// Scope for foreign WasmCode pointers.
WasmCodeRefScope code_ref_scope;
// We expect certain relocation info modes to never appear in {WasmCode}
@@ -365,36 +367,38 @@ void WasmCode::Validate() const {
case RelocInfo::WASM_CALL: {
Address target = it.rinfo()->wasm_call_address();
WasmCode* code = native_module_->Lookup(target);
- CHECK_NOT_NULL(code);
- CHECK_EQ(WasmCode::kJumpTable, code->kind());
- CHECK(code->contains(target));
+ DCHECK_NOT_NULL(code);
+ DCHECK_EQ(WasmCode::kJumpTable, code->kind());
+ DCHECK(code->contains(target));
break;
}
case RelocInfo::WASM_STUB_CALL: {
Address target = it.rinfo()->wasm_stub_call_address();
WasmCode* code = native_module_->Lookup(target);
- CHECK_NOT_NULL(code);
- CHECK_EQ(WasmCode::kJumpTable, code->kind());
- CHECK(code->contains(target));
+ DCHECK_NOT_NULL(code);
+ DCHECK_EQ(WasmCode::kJumpTable, code->kind());
+ DCHECK(code->contains(target));
break;
}
case RelocInfo::WASM_CANONICAL_SIG_ID: {
uint32_t sig_id = it.rinfo()->wasm_canonical_sig_id();
- CHECK_LE(sig_id, GetTypeCanonicalizer()->GetCurrentNumberOfTypes());
+ DCHECK_LE(sig_id, GetTypeCanonicalizer()->GetCurrentNumberOfTypes());
break;
}
case RelocInfo::WASM_CODE_POINTER_TABLE_ENTRY: {
+#ifdef ENABLE_SLOW_DCHECKS
WasmCodePointer call_target =
it.rinfo()->wasm_code_pointer_table_entry();
uint32_t function_index = function_index_map.at(call_target);
- CHECK_EQ(call_target,
- native_module_->GetCodePointerHandle(function_index));
+ DCHECK_EQ(call_target,
+ native_module_->GetCodePointerHandle(function_index));
+#endif
break;
}
case RelocInfo::INTERNAL_REFERENCE:
case RelocInfo::INTERNAL_REFERENCE_ENCODED: {
Address target = it.rinfo()->target_internal_reference();
- CHECK(contains(target));
+ DCHECK(contains(target));
break;
}
case RelocInfo::EXTERNAL_REFERENCE:
@@ -1115,115 +1119,122 @@ void NativeModule::LogWasmCodes(Isolate* isolate, Tagged<Script> script) {
}
}
-WasmCode* NativeModule::AddCodeForTesting(DirectHandle<Code> code,
+void NativeModule::ApplyRelocations(WritableJitAllocation& jit_allocation,
+ base::Vector<uint8_t> dst_code_bytes,
+ base::Vector<const uint8_t> reloc_info,
+ const CodeDesc& desc,
+ const JumpTablesRef& jump_tables,
+ WasmCode* reserved_code) const {
+ intptr_t delta = dst_code_bytes.begin() - desc.buffer;
+ int mode_mask =
+ RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
+ RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL) |
+ RelocInfo::ModeMask(RelocInfo::WASM_CODE_POINTER_TABLE_ENTRY) |
+ RelocInfo::ModeMask(RelocInfo::WASM_CODE_POINTER);
+ Address code_start = reinterpret_cast<Address>(dst_code_bytes.begin());
+ Address constant_pool_start = code_start + desc.constant_pool_offset;
+
+ for (WritableRelocIterator it(jit_allocation, dst_code_bytes, reloc_info,
+ constant_pool_start, mode_mask);
+ !it.done(); it.next()) {
+ RelocInfo::Mode mode = it.rinfo()->rmode();
+ if (RelocInfo::IsWasmCall(mode)) {
+ uint32_t call_tag = it.rinfo()->wasm_call_tag();
+ Address target = GetNearCallTargetForFunction(call_tag, jump_tables);
+ it.rinfo()->set_wasm_call_address(target);
+ } else if (RelocInfo::IsWasmStubCall(mode)) {
+ uint32_t stub_call_tag = it.rinfo()->wasm_call_tag();
+ DCHECK_LT(stub_call_tag,
+ static_cast<uint32_t>(Builtin::kFirstBytecodeHandler));
+ Builtin builtin = static_cast<Builtin>(stub_call_tag);
+ Address entry = GetJumpTableEntryForBuiltin(builtin, jump_tables);
+ it.rinfo()->set_wasm_stub_call_address(entry);
+ } else if (RelocInfo::IsWasmCodePointerTableEntry(mode)) {
+ uint32_t function_index =
+ it.rinfo()->wasm_code_pointer_table_entry().value();
+ WasmCodePointer target = GetCodePointerHandle(function_index);
+ it.rinfo()->set_wasm_code_pointer_table_entry(target, SKIP_ICACHE_FLUSH);
+ } else if (RelocInfo::IsWasmCodePointer(mode)) {
+ it.rinfo()->set_wasm_code_pointer(
+ reinterpret_cast<Address>(reserved_code));
+ } else {
+ it.rinfo()->apply(delta);
+ }
+ }
+}
+
+WasmCode* NativeModule::AddCodeForTesting(const WasmCompilationResult& result,
uint64_t signature_hash) {
- const size_t relocation_size = code->relocation_size();
- base::OwnedVector<uint8_t> reloc_info =
- base::OwnedCopyOf(code->relocation_start(), relocation_size);
- DirectHandle<TrustedByteArray> source_pos_table(code->source_position_table(),
- Isolate::Current());
- uint32_t source_pos_len = source_pos_table->ulength().value();
- base::OwnedVector<uint8_t> source_pos =
- base::OwnedCopyOf(source_pos_table->begin(), source_pos_len);
-
- static_assert(InstructionStream::kOnHeapBodyIsContiguous);
- base::Vector<const uint8_t> instructions(
- reinterpret_cast<uint8_t*>(code->body_start()),
- static_cast<size_t>(code->body_size()));
- const int stack_slots = code->stack_slots();
-
- // Metadata offsets in InstructionStream objects are relative to the start of
- // the metadata section, whereas WasmCode expects offsets relative to
- // instruction_start.
- const int base_offset = code->instruction_size();
- // TODO(jgruber,v8:8758): Remove this translation. It exists only because
- // InstructionStream objects contains real offsets but WasmCode expects an
- // offset of 0 to mean 'empty'.
+ DCHECK(result.succeeded());
+ const CodeDesc& desc = result.code_desc;
+ base::Vector<const uint8_t> reloc_info{
+ desc.buffer + desc.buffer_size - desc.reloc_size,
+ static_cast<size_t>(desc.reloc_size)};
+
const int safepoint_table_offset =
- code->has_safepoint_table() ? base_offset + code->safepoint_table_offset()
- : 0;
- const int handler_table_offset = base_offset + code->handler_table_offset();
- const int constant_pool_offset = base_offset + code->constant_pool_offset();
- const int code_comments_offset = base_offset + code->code_comments_offset();
- const int jump_table_info_offset =
- base_offset + code->jump_table_info_offset();
+ desc.safepoint_table_size == 0 ? 0 : desc.safepoint_table_offset;
+ const int handler_table_offset = desc.handler_table_offset;
+ const int constant_pool_offset = desc.constant_pool_offset;
+ const int code_comments_offset = desc.code_comments_offset;
+ const int jump_table_info_offset = desc.jump_table_info_offset;
+ const int instr_size = desc.instr_size;
base::RecursiveMutexGuard guard{&allocation_mutex_};
base::Vector<uint8_t> dst_code_bytes =
- code_allocator_.AllocateForCode(this, instructions.size());
+ code_allocator_.AllocateForCode(this, desc.instr_size);
+
+ // Reserve memory for WasmCode. We need the pointer for the reloc info.
+ WasmCode* reserved_code =
+ static_cast<WasmCode*>(operator new(sizeof(WasmCode)));
+
+ JumpTablesRef jump_tables =
+ FindJumpTablesForRegionLocked(base::AddressRegionOf(dst_code_bytes));
+
{
WritableJitAllocation jit_allocation =
ThreadIsolation::RegisterJitAllocation(
reinterpret_cast<Address>(dst_code_bytes.begin()),
dst_code_bytes.size(),
ThreadIsolation::JitAllocationType::kWasmCode, true);
- jit_allocation.CopyCode(0, instructions.begin(), instructions.size());
-
- // Apply the relocation delta by iterating over the RelocInfo.
- intptr_t delta = reinterpret_cast<Address>(dst_code_bytes.begin()) -
- code->instruction_start();
- int mode_mask =
- RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL) |
- RelocInfo::ModeMask(RelocInfo::WASM_CODE_POINTER_TABLE_ENTRY);
- auto jump_tables_ref =
- FindJumpTablesForRegionLocked(base::AddressRegionOf(dst_code_bytes));
- Address dst_code_addr = reinterpret_cast<Address>(dst_code_bytes.begin());
- Address constant_pool_start = dst_code_addr + constant_pool_offset;
- RelocIterator orig_it(*code, mode_mask);
- for (WritableRelocIterator it(jit_allocation, dst_code_bytes,
- reloc_info.as_vector(), constant_pool_start,
- mode_mask);
- !it.done(); it.next(), orig_it.next()) {
- RelocInfo::Mode mode = it.rinfo()->rmode();
- if (RelocInfo::IsWasmStubCall(mode)) {
- uint32_t stub_call_tag = orig_it.rinfo()->wasm_call_tag();
- DCHECK_LT(stub_call_tag,
- static_cast<uint32_t>(Builtin::kFirstBytecodeHandler));
- Builtin builtin = static_cast<Builtin>(stub_call_tag);
- Address entry = GetJumpTableEntryForBuiltin(builtin, jump_tables_ref);
- it.rinfo()->set_wasm_stub_call_address(entry);
- } else if (RelocInfo::IsWasmCodePointerTableEntry(mode)) {
- uint32_t function_index =
- it.rinfo()->wasm_code_pointer_table_entry().value();
- WasmCodePointer target = GetCodePointerHandle(function_index);
- it.rinfo()->set_wasm_code_pointer_table_entry(target,
- SKIP_ICACHE_FLUSH);
- } else {
- it.rinfo()->apply(delta);
- }
- }
+ jit_allocation.CopyCode(0, desc.buffer, desc.instr_size);
+ ApplyRelocations(jit_allocation, dst_code_bytes, reloc_info, desc,
+ jump_tables, reserved_code);
}
// Flush the i-cache after relocation.
FlushInstructionCache(dst_code_bytes.begin(), dst_code_bytes.size());
- std::unique_ptr<WasmCode> new_code{
- new WasmCode{this, // native_module
- kAnonymousFuncIndex, // index
- dst_code_bytes, // instructions
- stack_slots, // stack_slots
- 0, // ool_spills
- 0, // tagged_parameter_slots
- safepoint_table_offset, // safepoint_table_offset
- handler_table_offset, // handler_table_offset
- constant_pool_offset, // constant_pool_offset
- code_comments_offset, // code_comments_offset
- jump_table_info_offset, // jump_table_info_offset
- instructions.length(), // unpadded_binary_size
- {}, // trapping_instructions
- reloc_info.as_vector(), // reloc_info
- source_pos.as_vector(), // source positions
- {}, // inlining positions
- {}, // deopt data
- WasmCode::kWasmFunction, // kind
- ExecutionTier::kNone, // tier
- kNotForDebugging, // for_debugging
- signature_hash, // signature_hash
- {}}}; // effect handlers
- new_code->MaybePrint();
- new_code->Validate();
-
- return PublishCodeLocked(std::move(new_code),
+ std::unique_ptr<WasmCode> unique_code{new (reserved_code) WasmCode{
+ this,
+ kAnonymousFuncIndex,
+ dst_code_bytes,
+ static_cast<int>(result.frame_slot_count),
+ static_cast<int>(result.ool_spill_count),
+ result.tagged_parameter_slots,
+ safepoint_table_offset,
+ handler_table_offset,
+ constant_pool_offset,
+ code_comments_offset,
+ jump_table_info_offset,
+ instr_size,
+ result.trapping_instructions_data.as_vector(),
+ reloc_info,
+ result.source_positions.as_vector(),
+ result.inlining_positions.as_vector(),
+ result.deopt_data.as_vector(),
+ GetCodeKind(result),
+ result.result_tier,
+ result.for_debugging,
+ signature_hash,
+ result.effect_handlers.as_vector(),
+ result.frame_has_feedback_slot}};
+
+ unique_code->MaybePrint();
+ unique_code->Validate();
+
+ // Test code is anonymous and does not participate in assumption tracking.
+ DCHECK_NULL(result.assumptions);
+ return PublishCodeLocked(std::move(unique_code),
UnpublishedWasmCode::kNoAssumptions);
}
@@ -1336,7 +1347,7 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
ExecutionTier tier, ForDebugging for_debugging,
base::Vector<const uint8_t> effect_handlers, bool frame_has_feedback_slot,
base::Vector<uint8_t> dst_code_bytes, const JumpTablesRef& jump_tables) {
- base::Vector<uint8_t> reloc_info{
+ base::Vector<const uint8_t> reloc_info{
desc.buffer + desc.buffer_size - desc.reloc_size,
static_cast<size_t>(desc.reloc_size)};
@@ -1353,7 +1364,7 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
// Reserve memory for WasmCode. We need the pointer for the reloc info.
WasmCode* reserved_code =
- reinterpret_cast<WasmCode*>(operator new(sizeof(WasmCode)));
+ static_cast<WasmCode*>(operator new(sizeof(WasmCode)));
{
WritableJitAllocation jit_allocation = ThreadIsolation::LookupJitAllocation(
@@ -1362,44 +1373,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
true);
jit_allocation.CopyCode(0, desc.buffer, desc.instr_size);
- // Apply the relocation delta by iterating over the RelocInfo.
- intptr_t delta = dst_code_bytes.begin() - desc.buffer;
- int mode_mask =
- RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
- RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL) |
- RelocInfo::ModeMask(RelocInfo::WASM_CODE_POINTER_TABLE_ENTRY) |
- RelocInfo::ModeMask(RelocInfo::WASM_CODE_POINTER);
- Address code_start = reinterpret_cast<Address>(dst_code_bytes.begin());
- Address constant_pool_start = code_start + constant_pool_offset;
-
- for (WritableRelocIterator it(jit_allocation, dst_code_bytes, reloc_info,
- constant_pool_start, mode_mask);
- !it.done(); it.next()) {
- RelocInfo::Mode mode = it.rinfo()->rmode();
- if (RelocInfo::IsWasmCall(mode)) {
- uint32_t call_tag = it.rinfo()->wasm_call_tag();
- Address target = GetNearCallTargetForFunction(call_tag, jump_tables);
- it.rinfo()->set_wasm_call_address(target);
- } else if (RelocInfo::IsWasmStubCall(mode)) {
- uint32_t stub_call_tag = it.rinfo()->wasm_call_tag();
- DCHECK_LT(stub_call_tag,
- static_cast<uint32_t>(Builtin::kFirstBytecodeHandler));
- Builtin builtin = static_cast<Builtin>(stub_call_tag);
- Address entry = GetJumpTableEntryForBuiltin(builtin, jump_tables);
- it.rinfo()->set_wasm_stub_call_address(entry);
- } else if (RelocInfo::IsWasmCodePointerTableEntry(mode)) {
- uint32_t function_index =
- it.rinfo()->wasm_code_pointer_table_entry().value();
- WasmCodePointer target = GetCodePointerHandle(function_index);
- it.rinfo()->set_wasm_code_pointer_table_entry(target,
- SKIP_ICACHE_FLUSH);
- } else if (RelocInfo::IsWasmCodePointer(mode)) {
- it.rinfo()->set_wasm_code_pointer(
- reinterpret_cast<Address>(reserved_code));
- } else {
- it.rinfo()->apply(delta);
- }
- }
+ ApplyRelocations(jit_allocation, dst_code_bytes, reloc_info, desc,
+ jump_tables, reserved_code);
}
// Flush the i-cache after relocation.
@@ -1412,32 +1387,30 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
uint64_t signature_hash =
module_->signature_hash(GetTypeCanonicalizer(), index);
- // Construct WasmCode in place.
- WasmCode* code = new (reserved_code) WasmCode{this,
- index,
- dst_code_bytes,
- stack_slots,
- ool_spill_count,
- tagged_parameter_slots,
- safepoint_table_offset,
- handler_table_offset,
- constant_pool_offset,
- code_comments_offset,
- jump_table_info_offset,
- instr_size,
- trapping_instructions_data,
- reloc_info,
- source_position_table,
- inlining_positions,
- deopt_data,
- kind,
- tier,
- for_debugging,
- signature_hash,
- effect_handlers,
- frame_has_feedback_slot};
-
- std::unique_ptr<WasmCode> unique_code{code};
+ std::unique_ptr<WasmCode> unique_code{new (reserved_code)
+ WasmCode{this,
+ index,
+ dst_code_bytes,
+ stack_slots,
+ ool_spill_count,
+ tagged_parameter_slots,
+ safepoint_table_offset,
+ handler_table_offset,
+ constant_pool_offset,
+ code_comments_offset,
+ jump_table_info_offset,
+ instr_size,
+ trapping_instructions_data,
+ reloc_info,
+ source_position_table,
+ inlining_positions,
+ deopt_data,
+ kind,
+ tier,
+ for_debugging,
+ signature_hash,
+ effect_handlers,
+ frame_has_feedback_slot}};
unique_code->MaybePrint();
unique_code->Validate();
diff --git a/deps/v8/src/wasm/wasm-code-manager.h b/deps/v8/src/wasm/wasm-code-manager.h
index bab5eca796f..9f54c110103 100644
--- a/deps/v8/src/wasm/wasm-code-manager.h
+++ b/deps/v8/src/wasm/wasm-code-manager.h
@@ -46,6 +46,7 @@ namespace internal {
class CodeDesc;
class InstructionStream;
class Isolate;
+class WritableJitAllocation;
namespace wasm {
@@ -706,8 +707,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
base::Vector<const uint8_t> deopt_data, WasmCode::Kind kind,
ExecutionTier tier, base::Vector<const uint8_t> effect_handlers);
- // Adds anonymous code for testing purposes.
- WasmCode* AddCodeForTesting(DirectHandle<Code> code,
+ // Adds anonymous code for testing purposes. Requires an active
+ // {WasmCodeRefScope} and a successful {result} without assumptions.
+ WasmCode* AddCodeForTesting(const WasmCompilationResult& result,
uint64_t signature_hash) V8_LIFETIME_BOUND;
// Allocates and initializes the {lazy_compile_table_} and initializes the
@@ -1014,6 +1016,16 @@ class V8_EXPORT_PRIVATE NativeModule final {
const CodeSpaceData&, uint32_t slot_index,
Address target);
+ // Apply relocations to newly copied code in {dst_code_bytes}.
+ // {reserved_code} is the pre-allocated memory for the {WasmCode} object,
+ // needed for self-referential WASM_CODE_POINTER relocations. Does not require
+ // {allocation_mutex_}.
+ void ApplyRelocations(WritableJitAllocation& jit_allocation,
+ base::Vector<uint8_t> dst_code_bytes,
+ base::Vector<const uint8_t> reloc_info,
+ const CodeDesc& desc, const JumpTablesRef& jump_tables,
+ WasmCode* reserved_code) const;
+
// Called by the {WasmCodeAllocator} to register a new code space.
void AddCodeSpaceLocked(base::AddressRegion);
diff --git a/deps/v8/src/wasm/wasm-disassembler.cc b/deps/v8/src/wasm/wasm-disassembler.cc
index 53372adc9b6..b35ed43f7bb 100644
--- a/deps/v8/src/wasm/wasm-disassembler.cc
+++ b/deps/v8/src/wasm/wasm-disassembler.cc
@@ -115,13 +115,17 @@ void DisassembleFunction(const WasmModule* module, int func_index,
static constexpr char kHexChars[] = "0123456789abcdef";
static constexpr char kUpperHexChars[] = "0123456789ABCDEF";
-// Returns the log2 of the alignment, e.g. "4" means 2<<4 == 16 bytes.
+// Returns the log2 of the alignment, e.g. "4" means 1<<4 == 16 bytes.
// This is the same format as used in .wasm binary modules.
uint32_t GetDefaultAlignment(WasmOpcode opcode) {
switch (opcode) {
case kExprS128LoadMem:
case kExprS128StoreMem:
return 4;
+ case kExprI64LoadMem:
+ case kExprF64LoadMem:
+ case kExprI64StoreMem:
+ case kExprF64StoreMem:
case kExprS128Load8x8S:
case kExprS128Load8x8U:
case kExprS128Load16x4S:
@@ -133,31 +137,41 @@ uint32_t GetDefaultAlignment(WasmOpcode opcode) {
case kExprS128Load64Lane:
case kExprS128Store64Lane:
return 3;
+ case kExprI32LoadMem:
+ case kExprF32LoadMem:
+ case kExprI64LoadMem32S:
+ case kExprI64LoadMem32U:
+ case kExprI32StoreMem:
+ case kExprF32StoreMem:
+ case kExprI64StoreMem32:
case kExprS128Load32Splat:
case kExprS128Load32Zero:
case kExprS128Load32Lane:
case kExprS128Store32Lane:
return 2;
+ case kExprI32LoadMem16S:
+ case kExprI32LoadMem16U:
+ case kExprI64LoadMem16S:
+ case kExprI64LoadMem16U:
+ case kExprF32LoadMemF16:
+ case kExprI32StoreMem16:
+ case kExprI64StoreMem16:
+ case kExprF32StoreMemF16:
case kExprS128Load16Splat:
case kExprS128Load16Lane:
case kExprS128Store16Lane:
return 1;
+ case kExprI32LoadMem8S:
+ case kExprI32LoadMem8U:
+ case kExprI64LoadMem8S:
+ case kExprI64LoadMem8U:
+ case kExprI32StoreMem8:
+ case kExprI64StoreMem8:
case kExprS128Load8Splat:
case kExprS128Load8Lane:
case kExprS128Store8Lane:
return 0;
-#define CASE(Opcode, ...) \
- case kExpr##Opcode: \
- return GetLoadType(kExpr##Opcode).size_log_2();
- FOREACH_LOAD_MEM_OPCODE(CASE)
-#undef CASE
-#define CASE(Opcode, ...) \
- case kExpr##Opcode: \
- return GetStoreType(kExpr##Opcode).size_log_2();
- FOREACH_STORE_MEM_OPCODE(CASE)
-#undef CASE
-
#define CASE(Opcode, Type) \
case kExpr##Opcode: \
return ElementSizeLog2Of(MachineType::Type().representation());
diff --git a/deps/v8/src/wasm/wasm-engine.cc b/deps/v8/src/wasm/wasm-engine.cc
index 09ed7759a8d..47955e35f4c 100644
--- a/deps/v8/src/wasm/wasm-engine.cc
+++ b/deps/v8/src/wasm/wasm-engine.cc
@@ -9,6 +9,7 @@
#include "src/base/hashing.h"
#include "src/base/platform/time.h"
#include "src/base/small-vector.h"
+#include "src/codegen/cpu-features.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/debug/debug.h"
@@ -678,7 +679,7 @@ MaybeDirectHandle<WasmModuleObject> WasmEngine::SyncCompile(
// serializable. Instantiation may occur off a deserialized version of this
// object.
DirectHandle<WasmModuleObject> module_object =
- WasmModuleObject::New(isolate, std::move(native_module), script);
+ WasmModuleObject::New(isolate, script);
// Finish the Wasm script now and make it public to the debugger.
isolate->debug()->OnAfterCompile(script);
@@ -1025,7 +1026,7 @@ MaybeDirectHandle<WasmModuleObject> WasmEngine::ImportNativeModule(
GetOrCreateScript(isolate, shared_native_module, source_url);
native_module->LogWasmCodes(isolate, *script);
DirectHandle<WasmModuleObject> module_object =
- WasmModuleObject::New(isolate, std::move(shared_native_module), script);
+ WasmModuleObject::New(isolate, script);
{
base::MutexGuard lock(&mutex_);
DCHECK(isolates_.contains(isolate));
@@ -1212,6 +1213,12 @@ void WasmEngine::AddIsolate(Isolate* isolate) {
isolate->counters()->wasm_memory_protection_keys_support()->AddSample(
has_mpk ? 1 : 0);
+#if V8_TARGET_ARCH_X64
+ bool has_avx2 =
+ CpuFeatures::IsSupported(AVX) && CpuFeatures::IsSupported(AVX2);
+ isolate->counters()->wasm_avx2_support()->AddSample(has_avx2 ? 1 : 0);
+#endif
+
if (log_code) {
// Log existing wrappers (which are shared across isolates).
GetWasmImportWrapperCache()->LogForIsolate(isolate);
diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc
index 582631e38eb..abc56d40463 100644
--- a/deps/v8/src/wasm/wasm-external-refs.cc
+++ b/deps/v8/src/wasm/wasm-external-refs.cc
@@ -881,9 +881,9 @@ inline void* ArrayElementAddress(Tagged<WasmArray> array, uint32_t index,
}
} // namespace
-void array_copy_wrapper(Address raw_dst_array, uint32_t dst_index,
- Address raw_src_array, uint32_t src_index,
- uint32_t length) {
+DISABLE_TSAN void array_copy_wrapper(Address raw_dst_array, uint32_t dst_index,
+ Address raw_src_array, uint32_t src_index,
+ uint32_t length) {
DCHECK_GT(length, 0);
DisallowGarbageCollection no_gc;
Tagged<WasmArray> dst_array = Cast<WasmArray>(Tagged<Object>(raw_dst_array));
@@ -919,9 +919,11 @@ void array_copy_wrapper(Address raw_dst_array, uint32_t dst_index,
}
}
-void array_fill_wrapper(Address raw_array, uint32_t index, uint32_t length,
- uint32_t emit_write_barrier, uint32_t raw_type,
- Address initial_value_addr) {
+DISABLE_TSAN void array_fill_wrapper(Address raw_array, uint32_t index,
+ uint32_t length,
+ uint32_t emit_write_barrier,
+ uint32_t raw_type,
+ Address initial_value_addr) {
DisallowGarbageCollection no_gc;
ValueType type = ValueType::FromRawBitField(raw_type);
int8_t* initial_element_address = reinterpret_cast<int8_t*>(
diff --git a/deps/v8/src/wasm/wasm-js.cc b/deps/v8/src/wasm/wasm-js.cc
index 97709612398..efffb941cc5 100644
--- a/deps/v8/src/wasm/wasm-js.cc
+++ b/deps/v8/src/wasm/wasm-js.cc
@@ -165,11 +165,11 @@ void WasmStreaming::SetUrl(const char* url, size_t length) {
// static
std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
- Local<Value> value) {
+ Local<Data> data) {
TRACE_EVENT("v8.wasm", "wasm.WasmStreaming.Unpack");
i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate));
auto managed =
- i::Cast<i::CppGCManaged<WasmStreaming>>(Utils::OpenDirectHandle(*value));
+ i::Cast<i::CppGCManaged<WasmStreaming>>(Utils::OpenDirectHandle(*data));
return managed->ptr().as_shared_ptr();
}
@@ -785,7 +785,7 @@ void WasmStreamingCallbackForTesting(
auto [isolate, i_isolate, thrower] = js_api_scope.isolates_and_thrower();
std::shared_ptr<v8::WasmStreaming> streaming =
- v8::WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ v8::WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
// We don't check the buffer length up front, to allow d8 to test that the
// streaming decoder implementation handles overly large inputs correctly.
@@ -805,7 +805,7 @@ void WasmStreamingPromiseFailedCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<v8::WasmStreaming> streaming =
- v8::WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ v8::WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->Abort(info[0]);
}
@@ -1265,7 +1265,7 @@ void WebAssemblyInstantiateImpl(
DCHECK_EQ(info.Length(), 1);
Isolate* isolate2 = info.GetIsolate();
HandleScope scope(isolate2);
- Local<FixedArray> data = info.Data().As<FixedArray>();
+ Local<FixedArray> data = info.DataV2().As<FixedArray>();
DCHECK_EQ(3, data->Length());
Local<Context> context = data->Get(0).As<Context>();
Local<Promise::Resolver> promise_resolver =
@@ -1306,7 +1306,7 @@ void WebAssemblyInstantiateImpl(
DCHECK_EQ(1, info.Length());
HandleScope scope(info.GetIsolate());
Local<Promise::Resolver> instantiation_promise_resolver =
- info.Data().As<Promise::Resolver>();
+ info.DataV2().As<Value>().As<Promise::Resolver>();
instantiation_promise_resolver
->Reject(info.GetIsolate()->GetCurrentContext(), info[0])
@@ -2272,9 +2272,8 @@ i::DirectHandle<i::JSFunction> NewPromisingWasmExportedFunction(
i::DirectHandle<i::Code> wrapper;
if (!i::wasm::IsJSCompatibleSignature(sig)) {
// If the signature is incompatible with JS, the original export will have
- // compiled an incompatible signature wrapper, so just reuse that.
- wrapper =
- i::DirectHandle<i::Code>(data->wrapper_code(i_isolate), i_isolate);
+ // compiled an incompatible signature wrapper, so fetch it from the cache.
+ wrapper = i::WasmExportedFunction::GetWrapper(i_isolate, sig);
} else {
wrapper = BUILTIN_CODE(i_isolate, WasmPromising);
}
@@ -2290,11 +2289,11 @@ i::DirectHandle<i::JSFunction> NewPromisingWasmExportedFunction(
if (func_index >= num_imported_functions) {
implicit_arg = trusted_instance_data;
} else {
- implicit_arg = i_isolate->factory()->NewWasmImportData(direct_handle(
+ implicit_arg = direct_handle(
i::TrustedCast<i::WasmImportData>(
trusted_instance_data->dispatch_table_for_imports()->implicit_arg(
func_index)),
- i_isolate));
+ i_isolate);
}
i::DirectHandle<i::WasmInternalFunction> internal =
@@ -2303,9 +2302,6 @@ i::DirectHandle<i::JSFunction> NewPromisingWasmExportedFunction(
trusted_instance_data->GetCallTarget(func_index), sig);
i::DirectHandle<i::WasmFuncRef> func_ref =
i_isolate->factory()->NewWasmFuncRef(internal, rtt);
- if (func_index < num_imported_functions) {
- i::TrustedCast<i::WasmImportData>(implicit_arg)->set_call_origin(*internal);
- }
i::DirectHandle<i::JSFunction> result = i::WasmExportedFunction::New(
i_isolate, trusted_instance_data, func_ref, internal,
diff --git a/deps/v8/src/wasm/wasm-linkage.h b/deps/v8/src/wasm/wasm-linkage.h
index e8748c06a68..b4d6bf04e63 100644
--- a/deps/v8/src/wasm/wasm-linkage.h
+++ b/deps/v8/src/wasm/wasm-linkage.h
@@ -159,6 +159,15 @@ constexpr bool kIsBigEndianOnSim = true;
#else
constexpr bool kIsBigEndianOnSim = false;
#endif
+// Platforms where single-precision floats are stored NaN-boxed in FP registers
+// (upper 32 bits all ones). On these, the generic JS-to-wasm wrapper must write
+// f32 parameters in NaN-boxed 64-bit form, because the assembly wrapper reloads
+// them with a 64-bit FP load.
+#if V8_TARGET_ARCH_RISCV64
+constexpr bool kFP32NeedNanBox = true;
+#else
+constexpr bool kFP32NeedNanBox = false;
+#endif
// The parameter index where the trusted instance data should be placed in wasm
// call descriptors. This is used by the Int64Lowering::LowerNode method.
diff --git a/deps/v8/src/wasm/wasm-memory-map-descriptor.h b/deps/v8/src/wasm/wasm-memory-map-descriptor.h
index f8846fe4781..897f863b252 100644
--- a/deps/v8/src/wasm/wasm-memory-map-descriptor.h
+++ b/deps/v8/src/wasm/wasm-memory-map-descriptor.h
@@ -10,13 +10,14 @@
#include "include/v8-wasm.h"
#include "src/handles/handles.h"
#include "src/objects/js-objects.h"
+#include "src/sandbox/cppheap-pointer-tag.h"
namespace v8::internal::wasm {
class WasmMemoryMapDescriptor final : public v8::Object::Wrappable {
public:
static constexpr v8::CppHeapPointerTag kPointerTag =
- v8::CppHeapPointerTag::kWasmMemoryMapDescriptorTag;
+ kWasmMemoryMapDescriptorTag;
using PlatformFileDescriptor =
v8::WasmMemoryMapDescriptor::WasmFileDescriptor;
diff --git a/deps/v8/src/wasm/wasm-objects-inl.h b/deps/v8/src/wasm/wasm-objects-inl.h
index 9e467a624d4..693dec1f44f 100644
--- a/deps/v8/src/wasm/wasm-objects-inl.h
+++ b/deps/v8/src/wasm/wasm-objects-inl.h
@@ -690,20 +690,6 @@ void WasmImportData::clear_importing_instance_data() {
protected_importing_instance_data_.store(this, {}, SKIP_WRITE_BARRIER);
}
-Tagged<TrustedObject> WasmImportData::call_origin() const {
- DCHECK(has_call_origin());
- return protected_call_origin_.load();
-}
-void WasmImportData::set_call_origin(Tagged<TrustedObject> value,
- WriteBarrierMode mode) {
- protected_call_origin_.store(this, value, mode);
-}
-bool WasmImportData::has_call_origin() const {
- return !protected_call_origin_.load().is_null();
-}
-void WasmImportData::clear_call_origin() {
- protected_call_origin_.store(this, {}, SKIP_WRITE_BARRIER);
-}
Tagged<NativeContext> WasmImportData::native_context() const {
return native_context_.load();
@@ -747,13 +733,6 @@ void WasmImportData::set_suspend(wasm::Suspend value) {
set_bit_field(SuspendField::update(bit_field(), value));
}
-uint32_t WasmImportData::table_slot() const {
- return TableSlotField::decode(bit_field());
-}
-
-void WasmImportData::set_table_slot(uint32_t value) {
- set_bit_field(TableSlotField::update(bit_field(), value));
-}
void WasmImportData::clear_padding() {
#if TAGGED_SIZE_8_BYTES
@@ -838,14 +817,6 @@ bool WasmFuncRef::has_internal() const { return !trusted_internal_.is_empty(); }
void WasmFuncRef::clear_internal() { trusted_internal_.clear(this); }
// WasmFunctionData
-Tagged<Code> WasmFunctionData::wrapper_code(IsolateForSandbox isolate) const {
- return wrapper_code_.load(isolate);
-}
-void WasmFunctionData::set_wrapper_code(Tagged<Code> value,
- WriteBarrierMode mode) {
- wrapper_code_.store(this, value, mode);
-}
-
Tagged<WasmInternalFunction> WasmFunctionData::internal() const {
DCHECK(has_internal());
return protected_internal_.load();
diff --git a/deps/v8/src/wasm/wasm-objects.cc b/deps/v8/src/wasm/wasm-objects.cc
index e29f1dc3f94..4c82b3c9722 100644
--- a/deps/v8/src/wasm/wasm-objects.cc
+++ b/deps/v8/src/wasm/wasm-objects.cc
@@ -115,25 +115,13 @@ using WasmModule = wasm::WasmModule;
// static
DirectHandle<WasmModuleObject> WasmModuleObject::New(
- Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
- DirectHandle<Script> script) {
- DirectHandle<CppGCManaged<wasm::NativeModule>> managed_native_module;
- if (script->type() == Script::Type::kWasm) {
- managed_native_module = direct_handle(
- Cast<CppGCManaged<wasm::NativeModule>>(
- script->wasm_managed_native_module()),
- isolate);
- } else {
- const WasmModule* module = native_module->module();
- size_t memory_estimate =
- native_module->committed_code_space() +
- wasm::WasmCodeManager::EstimateNativeModuleMetaDataSize(module);
- managed_native_module = CppGCManaged<wasm::NativeModule>::Create(
- isolate, memory_estimate, std::move(native_module));
- }
+ Isolate* isolate, DirectHandle<Script> script) {
+ DCHECK_EQ(script->type(), Script::Type::kWasm);
DirectHandle<WasmModuleObject> module_object = Cast<WasmModuleObject>(
isolate->factory()->NewJSObject(isolate->wasm_module_constructor()));
- module_object->set_managed_native_module(*managed_native_module);
+ module_object->set_managed_native_module(
+ Cast<CppGCManaged<wasm::NativeModule>>(
+ script->wasm_managed_native_module()));
module_object->set_script(*script);
return module_object;
}
@@ -642,14 +630,6 @@ void WasmTableObject::UpdateDispatchTable(
SBXCHECK(FunctionSigMatchesTable(sig_id, dispatch_table->table_type()));
- if (v8_flags.wasm_generic_wrapper && IsWasmImportData(*implicit_arg)) {
- auto import_data = TrustedCast<WasmImportData>(implicit_arg);
- DirectHandle<WasmImportData> new_import_data =
- isolate->factory()->NewWasmImportData(import_data);
- new_import_data->set_call_origin(*dispatch_table);
- new_import_data->set_table_slot(entry_index);
- implicit_arg = new_import_data;
- }
std::optional<std::shared_ptr<wasm::WasmWrapperHandle>> maybe_wrapper =
target_instance_data->dispatch_table_for_imports()->MaybeGetWrapperHandle(
@@ -1328,11 +1308,6 @@ void ImportedFunctionEntry::SetWasmToWrapper(
isolate->factory()->NewWasmImportData(callable, suspend,
importing_instance_data_, sig);
- if (!wrapper_handle->has_code()) {
- import_data->SetIndexInTableAsCallOrigin(
- importing_instance_data_->dispatch_table_for_imports(), index_);
- }
-
DisallowGarbageCollection no_gc;
Tagged<WasmDispatchTableForImports> dispatch_table =
importing_instance_data_->dispatch_table_for_imports();
@@ -1573,17 +1548,16 @@ DirectHandle<WasmTrustedInstanceData> WasmTrustedInstanceData::New(
instance_object->set_module_object(*module_object);
trusted_data->set_instance_object(*instance_object);
- // Insert the new instance into the scripts weak list of instances. This
+ // Insert the new instance into the script's weak list of instances. This
// list is used for breakpoints affecting all instances belonging to the
// script.
- if (module_object->script()->type() == Script::Type::kWasm) {
- DirectHandle<WeakArrayList> weak_instance_list(
- module_object->script()->wasm_weak_instance_list(), isolate);
- weak_instance_list =
- WeakArrayList::Append(isolate, weak_instance_list,
- MaybeObjectDirectHandle::Weak(instance_object));
- module_object->script()->set_wasm_weak_instance_list(*weak_instance_list);
- }
+ DCHECK_EQ(module_object->script()->type(), Script::Type::kWasm);
+ DirectHandle<WeakArrayList> weak_instance_list(
+ module_object->script()->wasm_weak_instance_list(), isolate);
+ weak_instance_list =
+ WeakArrayList::Append(isolate, weak_instance_list,
+ MaybeObjectDirectHandle::Weak(instance_object));
+ module_object->script()->set_wasm_weak_instance_list(*weak_instance_list);
return trusted_data;
}
@@ -1722,11 +1696,9 @@ V8_INLINE DirectHandle<WasmExportedFunction> CreateExportedFunction(
DirectHandle<Code> wrapper_code =
WasmExportedFunction::GetWrapper(isolate, sig);
int arity = static_cast<int>(sig->parameter_count());
- DirectHandle<WasmExportedFunction> external = WasmExportedFunction::New(
- isolate, trusted_instance_data, func_ref, internal_function, arity,
- wrapper_code, function_index, wasm::kNoPromise);
- internal_function->set_external(*external);
- return external;
+ return WasmExportedFunction::New(isolate, trusted_instance_data, func_ref,
+ internal_function, arity, wrapper_code,
+ function_index, wasm::kNoPromise);
}
} // namespace
@@ -1856,21 +1828,6 @@ DirectHandle<Code> WasmExportedFunction::GetWrapper(
return compiled;
}
-void WasmImportData::SetIndexInTableAsCallOrigin(
- Tagged<WasmDispatchTable> table, int entry_index) {
- set_call_origin(table);
- set_table_slot(entry_index);
-}
-void WasmImportData::SetIndexInTableAsCallOrigin(
- Tagged<WasmDispatchTableForImports> table, int entry_index) {
- set_call_origin(table);
- set_table_slot(entry_index);
-}
-
-void WasmImportData::SetFuncRefAsCallOrigin(Tagged<WasmInternalFunction> func) {
- set_call_origin(func);
-}
-
Address WasmTrustedInstanceData::GetGlobalStorage(
const wasm::WasmGlobal& global, const DisallowGarbageCollection&) {
if (global.mutability && global.imported) {
@@ -2064,6 +2021,11 @@ DirectHandle<WasmCustomMap> WasmCustomMap::AllocateUninitialized(
type.struct_type, described_index, described_size,
described_instance_type, rtt_parent, num_supertypes, map);
DisallowGarbageCollection no_gc;
+ DCHECK(!type.is_shared);
+ // TODO(manoskouk): If the above check is violated (i.e. we have shared custom
+ // descriptors), remove it and add a publish guard:
+ // SharedObjectConditionalSafePublishGuard publish_guard(*descriptor,
+ // type.is_shared);
if (!prototype.is_null()) {
Map::SetPrototype(isolate, descriptor, prototype);
}
@@ -2588,24 +2550,7 @@ DirectHandle<WasmDispatchTable> WasmDispatchTable::Grow(
new_table->WriteField<int>(kLengthOffset, new_length);
for (uint32_t i = 0; i < old_length; ++i) {
WasmCodePointer call_target = old_table->target(i);
- // Update any stored call origins, so that future compiled wrappers
- // get installed into the new dispatch table.
Tagged<Object> implicit_arg = old_table->implicit_arg(i);
- if (Is<WasmImportData>(implicit_arg)) {
- Tagged<WasmImportData> import_data =
- TrustedCast<WasmImportData>(implicit_arg);
- // After installing a compiled wrapper, we don't set or update
- // call origins any more.
- if (import_data->has_call_origin()) {
- if (import_data->call_origin() == *old_table) {
- import_data->set_call_origin(*new_table);
- } else {
- DCHECK(v8_flags.wasm_jitless ||
- wasm::GetWasmImportWrapperCache()->IsCompiledWrapper(
- call_target));
- }
- }
- }
if (implicit_arg == Smi::zero()) {
DispatchTableClear(*new_table, i, kNewEntry);
@@ -2883,12 +2828,13 @@ DirectHandle<WasmCapiFunction> WasmCapiFunction::New(
DirectHandle<Map> rtt = isolate->factory()->wasm_func_ref_map();
DirectHandle<WasmCapiFunctionData> fun_data =
- isolate->factory()->NewWasmCapiFunctionData(
- call_target, embedder_data, BUILTIN_CODE(isolate, Illegal), rtt, sig);
+ isolate->factory()->NewWasmCapiFunctionData(call_target, embedder_data,
+ rtt, sig);
DirectHandle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfoForWasmCapiFunction(fun_data);
DirectHandle<JSFunction> result =
Factory::JSFunctionBuilder{isolate, shared, isolate->native_context()}
+ .set_code(BUILTIN_CODE(isolate, Illegal))
.Build();
fun_data->internal()->set_external(*result);
return Cast<WasmCapiFunction>(result);
@@ -2899,15 +2845,6 @@ DirectHandle<WasmExportedFunction> WasmExportedFunction::New(
DirectHandle<WasmFuncRef> func_ref,
DirectHandle<WasmInternalFunction> internal_function, int arity,
DirectHandle<Code> export_wrapper) {
- DCHECK(
- CodeKind::JS_TO_WASM_FUNCTION == export_wrapper->kind() ||
- (export_wrapper->is_builtin() &&
- (export_wrapper->builtin_id() == Builtin::kJSToWasmWrapper ||
-#if V8_ENABLE_DRUMBRAKE
- export_wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapper ||
-#endif // V8_ENABLE_DRUMBRAKE
- export_wrapper->builtin_id() == Builtin::kWasmPromising ||
- export_wrapper->builtin_id() == Builtin::kWasmStressSwitch)));
int func_index = internal_function->function_index();
wasm::Promise promise =
export_wrapper->builtin_id() == Builtin::kWasmPromising
@@ -2922,10 +2859,19 @@ DirectHandle<WasmExportedFunction> WasmExportedFunction::New(
DirectHandle<WasmFuncRef> func_ref,
DirectHandle<WasmInternalFunction> internal_function, int arity,
DirectHandle<Code> export_wrapper, int func_index, wasm::Promise promise) {
+ DCHECK(
+ CodeKind::JS_TO_WASM_FUNCTION == export_wrapper->kind() ||
+ (export_wrapper->is_builtin() &&
+ (export_wrapper->builtin_id() == Builtin::kJSToWasmWrapper ||
+#if V8_ENABLE_DRUMBRAKE
+ export_wrapper->builtin_id() == Builtin::kJSToWasmInterpreterWrapper ||
+#endif // V8_ENABLE_DRUMBRAKE
+ export_wrapper->builtin_id() == Builtin::kWasmPromising ||
+ export_wrapper->builtin_id() == Builtin::kWasmStressSwitch)));
Factory* factory = isolate->factory();
DirectHandle<WasmExportedFunctionData> function_data =
factory->NewWasmExportedFunctionData(
- export_wrapper, instance_data, func_ref, internal_function,
+ instance_data, func_ref, internal_function,
v8_flags.wasm_wrapper_tiering_budget, promise);
#if V8_ENABLE_DRUMBRAKE
@@ -2954,6 +2900,7 @@ DirectHandle<WasmExportedFunction> WasmExportedFunction::New(
DirectHandle<JSFunction> js_function =
Factory::JSFunctionBuilder{isolate, shared, context}
.set_map(function_map)
+ .set_code(export_wrapper)
.Build();
// According to the spec, exported functions should not have a [[Construct]]
@@ -2964,7 +2911,7 @@ DirectHandle<WasmExportedFunction> WasmExportedFunction::New(
} else {
shared->set_script(*isolate->factory()->undefined_value(), kReleaseStore);
}
- function_data->internal()->set_external(*js_function);
+ internal_function->set_external(*js_function);
return Cast<WasmExportedFunction>(js_function);
}
@@ -3024,6 +2971,7 @@ DirectHandle<Map> CreateStructMap(
opt_native_context, instance_type, map_instance_size, elements_kind,
inobject_properties);
}
+ SharedObjectConditionalSafePublishGuard publish_guard(*map, shared);
map->set_wasm_type_info(*type_info);
map->set_is_extensible(false);
WasmStruct::EncodeInstanceSizeInMap(real_instance_size, *map);
@@ -3056,6 +3004,7 @@ DirectHandle<Map> CreateArrayMap(Isolate* isolate,
: isolate->factory()->NewContextlessMap(
instance_type, map_instance_size, elements_kind,
inobject_properties);
+ SharedObjectConditionalSafePublishGuard publish_guard(*map, shared);
map->set_wasm_type_info(*type_info);
map->SetInstanceDescriptors(*isolate->factory()->empty_descriptor_array(), 0,
SKIP_WRITE_BARRIER);
diff --git a/deps/v8/src/wasm/wasm-objects.h b/deps/v8/src/wasm/wasm-objects.h
index 957d019e33a..46b096c09a8 100644
--- a/deps/v8/src/wasm/wasm-objects.h
+++ b/deps/v8/src/wasm/wasm-objects.h
@@ -167,11 +167,9 @@ V8_OBJECT class WasmModuleObject : public JSObject {
static const int kScriptOffsetEnd;
static const int kHeaderSize;
- // Creates a new {WasmModuleObject} for an existing {NativeModule} that is
- // reference counted and might be shared between multiple Isolates.
+ // Creates a new {WasmModuleObject} for an existing {Script} of type {kWasm}.
V8_EXPORT_PRIVATE static DirectHandle<WasmModuleObject> New(
- Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
- DirectHandle<Script> script);
+ Isolate* isolate, DirectHandle<Script> script);
// Get the module name, if set. Returns an empty handle otherwise.
static MaybeDirectHandle<String> GetModuleNameOrNull(
@@ -1292,7 +1290,6 @@ V8_OBJECT class WasmFunctionData : public ExposedTrustedObject {
V8_IT_OWN_TYPE;
public:
- DECL_CODE_POINTER_ACCESSORS(wrapper_code)
DECL_PROTECTED_POINTER_ACCESSORS(internal, WasmInternalFunction)
inline Tagged<WasmFuncRef> func_ref() const;
@@ -1314,7 +1311,6 @@ V8_OBJECT class WasmFunctionData : public ExposedTrustedObject {
static const int kSize;
public:
- CodePointerMember wrapper_code_;
TaggedMember<WasmFuncRef> func_ref_;
TaggedMember<Smi> js_promise_flags_;
ProtectedTaggedMember<WasmInternalFunction> protected_internal_;
@@ -1367,8 +1363,7 @@ inline constexpr int WasmExportedFunctionData::kSize =
// The WasmImportData is passed to non-wasm imports in place of the
// WasmTrustedInstanceData. It is used in import wrappers (wasm-to-*) to load
-// needed information, and is used during wrapper tiering to know which
-// call site to patch (see the `call_origin` field).
+// needed information, and for tier-up of wasm-to-js wrappers.
V8_OBJECT class WasmImportData : public TrustedObject {
public:
// Dispatched behavior.
@@ -1380,10 +1375,6 @@ V8_OBJECT class WasmImportData : public TrustedObject {
// This field is null for C-API functions (WasmCapiFunctionData).
DECL_PROTECTED_POINTER_ACCESSORS(importing_instance_data,
WasmTrustedInstanceData)
- // `call_origin` records which place to patch on wrapper tier-up:
- // - WasmInternalFunction: a func ref
- // - WasmDispatchTable: a table; the slot is in the {bit_field}.
- DECL_PROTECTED_POINTER_ACCESSORS(call_origin, TrustedObject)
inline Tagged<NativeContext> native_context() const;
inline void set_native_context(Tagged<NativeContext> value,
@@ -1404,28 +1395,14 @@ V8_OBJECT class WasmImportData : public TrustedObject {
inline void set_bit_field(uint32_t value);
DECL_PRIMITIVE_ACCESSORS(suspend, wasm::Suspend)
- DECL_PRIMITIVE_ACCESSORS(table_slot, uint32_t)
inline void clear_padding();
- static constexpr int kInvalidCallOrigin = 0;
-
- void SetIndexInTableAsCallOrigin(Tagged<WasmDispatchTable> table,
- int entry_index);
- void SetIndexInTableAsCallOrigin(Tagged<WasmDispatchTableForImports> table,
- int entry_index);
- void SetFuncRefAsCallOrigin(Tagged<WasmInternalFunction> func);
-
class BodyDescriptor;
// Usage of the {bit_field()}.
// "Suspend" is always present.
using SuspendField = base::BitField<wasm::Suspend, 0, 1>;
- // "TableSlot" is populated when {protected_call_origin} is a
- // {WasmDispatchTable}, and describes the slot in that table.
- static constexpr int kTableSlotBits = 24;
- static_assert(wasm::kV8MaxWasmTableSize < (1u << kTableSlotBits));
- using TableSlotField = SuspendField::Next<uint32_t, kTableSlotBits>;
static const int kHeaderSize;
static const int kSize;
@@ -1433,7 +1410,6 @@ V8_OBJECT class WasmImportData : public TrustedObject {
public:
ProtectedTaggedMember<WasmTrustedInstanceData>
protected_importing_instance_data_;
- ProtectedTaggedMember<TrustedObject> protected_call_origin_;
TaggedMember<NativeContext> native_context_;
TaggedMember<UnionOf<JSReceiver, Undefined>> callable_;
TaggedMember<Cell> wrapper_budget_;
diff --git a/deps/v8/src/wasm/wasm-objects.tq b/deps/v8/src/wasm/wasm-objects.tq
index 4d73d6dd41e..30d05f7537a 100644
--- a/deps/v8/src/wasm/wasm-objects.tq
+++ b/deps/v8/src/wasm/wasm-objects.tq
@@ -45,19 +45,13 @@ extern class WasmInstanceObject extends JSObject {
// The WasmImportData is passed to non-wasm imports in place of the
// WasmTrustedInstanceData. It is used in import wrappers (wasm-to-*) to load
-// needed information, and is used during wrapper tiering to know which
-// call site to patch (see the `call_origin` field).
+// needed information, and for tier-up of wasm-to-js wrappers.
@cppObjectLayoutDefinition
extern class WasmImportData extends TrustedObject {
// The instance data of the importing instance. It is used to load memory
// start/size for fast API calls, and for tier-up of wasm-to-js wrappers.
// Use the '.importing_instance_data' macro to read this from torque code.
protected_importing_instance_data: ProtectedPointer<WasmTrustedInstanceData>;
- // `call_origin` records which place to patch on wrapper tier-up:
- // - WasmInternalFunction: a func ref
- // - WasmDispatchTable: a table; the slot is in the {bit_field}.
- protected_call_origin:
- ProtectedPointer<WasmInternalFunction|WasmDispatchTable>;
native_context: NativeContext;
callable: JSReceiver|Undefined;
// Contains a Smi; boxed so that generated code can update the value.
@@ -125,8 +119,6 @@ extern operator '.internal' macro LoadWasmInternalFunctionFromFuncRef(
// Exposed via SharedFunctionInfo::trusted_function_data.
@cppObjectLayoutDefinition
extern class WasmFunctionData extends ExposedTrustedObject {
- // Used for calling this function from JavaScript.
- wrapper_code: TrustedPointer<Code>;
// The function reference for this function object. This is used when
// converting a JS function back to the wasm-side func ref.
func_ref: WasmFuncRef;
diff --git a/deps/v8/src/wasm/wasm-opcodes.h b/deps/v8/src/wasm/wasm-opcodes.h
index a78a0dea725..3d18b6a39ad 100644
--- a/deps/v8/src/wasm/wasm-opcodes.h
+++ b/deps/v8/src/wasm/wasm-opcodes.h
@@ -800,10 +800,11 @@ V8_EXPORT_PRIVATE bool IsJSCompatibleSignature(const CanonicalSig* sig);
#define FOREACH_ATOMIC_GC_OPCODE(V) /* Force 80 columns */ \
V(Pause, 0xfe04, _, "pause") \
- /* Adjust the next three when the spec defines them. */ \
+ /* Adjust the next four when the spec defines them. */ \
V(StructWait, 0xfe05, _, "struct.wait") \
V(WaitqueueNotify, 0xfe06, _, "waitqueue.notify") \
V(WaitqueueNew, 0xfe07, _, "waitqueue.new") \
+ V(ArrayWait, 0xfe08, _, "array.wait") \
V(Publish, 0xfe0f, _, "publish") \
V(StructAtomicGet, 0xfe5c, _, "struct.atomic.get") \
V(StructAtomicGetS, 0xfe5d, _, "struct.atomic.get_s") \
diff --git a/deps/v8/src/wasm/wasm-serialization.cc b/deps/v8/src/wasm/wasm-serialization.cc
index 83cd5af3dcb..de8e70d82b0 100644
--- a/deps/v8/src/wasm/wasm-serialization.cc
+++ b/deps/v8/src/wasm/wasm-serialization.cc
@@ -1255,7 +1255,7 @@ MaybeDirectHandle<WasmModuleObject> DeserializeNativeModule(
DirectHandle<Script> script =
wasm_engine->GetOrCreateScript(isolate, shared_native_module, source_url);
DirectHandle<WasmModuleObject> module_object =
- WasmModuleObject::New(isolate, shared_native_module, script);
+ WasmModuleObject::New(isolate, script);
// Finish the Wasm script now and make it public to the debugger.
isolate->debug()->OnAfterCompile(script);
diff --git a/deps/v8/src/wasm/wasm-wrapper-cache-inl.h b/deps/v8/src/wasm/wasm-wrapper-cache-inl.h
index 22f0a1ca3a8..11bbf70a0bb 100644
--- a/deps/v8/src/wasm/wasm-wrapper-cache-inl.h
+++ b/deps/v8/src/wasm/wasm-wrapper-cache-inl.h
@@ -72,10 +72,10 @@ WasmCode* WasmWrapperCache<CacheKey>::ModificationScope::AddWrapper(
DCHECK(!RelocInfo::IsWasmStubCall(it.rinfo()->rmode()));
it.rinfo()->apply(delta);
}
+ FlushInstructionCache(code_space.begin(), code_space.size());
jit_allocation.UpdateWasmCodePointer(wrapper_handle->code_pointer(),
signature_hash);
}
- FlushInstructionCache(code_space.begin(), code_space.size());
const int frame_slot_count = result.frame_slot_count;
const int ool_spill_count = result.ool_spill_count;
constexpr bool frame_has_feedback_slot = false;
diff --git a/deps/v8/test/benchmarks/cpp/BUILD.gn b/deps/v8/test/benchmarks/cpp/BUILD.gn
index 2a50d6a0500..4f870a8772b 100644
--- a/deps/v8/test/benchmarks/cpp/BUILD.gn
+++ b/deps/v8/test/benchmarks/cpp/BUILD.gn
@@ -63,6 +63,8 @@ if (v8_enable_google_benchmark) {
deps = [
"//:v8",
+ "//:v8_internal_headers",
+ "//:v8_libbase",
"//third_party/google_benchmark_chrome:google_benchmark",
]
}
@@ -81,6 +83,7 @@ if (v8_enable_google_benchmark) {
deps = [
"//:v8",
+ "//:v8_libbase",
"//third_party/google_benchmark_chrome:google_benchmark",
]
}
diff --git a/deps/v8/test/benchmarks/cpp/bindings.cc b/deps/v8/test/benchmarks/cpp/bindings.cc
index b80723fec04..ae2c3685f69 100644
--- a/deps/v8/test/benchmarks/cpp/bindings.cc
+++ b/deps/v8/test/benchmarks/cpp/bindings.cc
@@ -350,16 +350,15 @@ class ManagedBindings : public BindingsBenchmarkBase<ManagedBindings> {
WrapperTypeInfo* info,
WrappableBase* wrappable) {
// Set V8 to C++ reference.
- v8::Object::Wrap<v8::CppHeapPointerTag::kTagForTesting>(isolate, v8_wrapper,
- wrappable);
+ v8::Object::Wrap<v8::internal::kTagForTesting>(isolate, v8_wrapper,
+ wrappable);
// Set C++ to V8 reference.
wrappable->SetWrapper(isolate, v8_wrapper);
}
template <typename T>
static V8_INLINE T* Unwrap(v8::Isolate* isolate, v8::Local<v8::Object> thiz) {
- return v8::Object::Unwrap<v8::CppHeapPointerTag::kTagForTesting, T>(isolate,
- thiz);
+ return v8::Object::Unwrap<v8::internal::kTagForTesting, T>(isolate, thiz);
}
static void SetupContextTemplate(
diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn
index fdd414cdb6a..396472aeb47 100644
--- a/deps/v8/test/cctest/BUILD.gn
+++ b/deps/v8/test/cctest/BUILD.gn
@@ -99,6 +99,7 @@ v8_cluster_source_set("cctest_sources") {
"../common/node-observer-tester.h",
"../common/value-helper.cc",
"../common/value-helper.h",
+ "../common/version-utils.h",
"cctest-utils.h",
"collector.h",
"expression-type-collector-macros.h",
diff --git a/deps/v8/test/cctest/compiler/test-code-generator.cc b/deps/v8/test/cctest/compiler/test-code-generator.cc
index 3e1b186c0c2..004525919d8 100644
--- a/deps/v8/test/cctest/compiler/test-code-generator.cc
+++ b/deps/v8/test/cctest/compiler/test-code-generator.cc
@@ -23,9 +23,11 @@
#include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/function-tester.h"
#include "test/common/code-assembler-tester.h"
+#include "test/common/flag-utils.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/compiler/wasm-compiler.h"
+#include "src/wasm/function-compiler.h"
#include "src/wasm/wasm-code-pointer-table-inl.h"
#include "src/wasm/wasm-engine.h"
#endif // V8_ENABLE_WEBASSEMBLY
@@ -1186,6 +1188,12 @@ class CodeGeneratorTester {
~CodeGeneratorTester() { delete generator_; }
+ static void AssembleConstructFrameForTest(CodeGenerator* generator) {
+ generator->masm()->CodeEntry();
+ generator->frame_access_state()->MarkHasFrame(true);
+ generator->AssembleConstructFrame();
+ }
+
std::vector<std::pair<LocationOperand, LocationOperand>>::iterator
GetSpillSlot(InstructionOperand* op) {
if (op->IsAnyStackSlot()) {
@@ -1631,6 +1639,44 @@ TEST(AssembleTailCallGap) {
}
}
+#if V8_TARGET_ARCH_X64
+TEST(TurboFanFrameSlotAlignment) {
+ FLAG_SCOPE(enforce_x64_16byte_alignment);
+ TestEnvironment env;
+ Isolate* isolate = env.main_isolate();
+ Linkage linkage(env.test_descriptor());
+
+ // Test both odd fixed headers (JSFunction = 5 slots, Stub = 3 slots)
+ // and even fixed headers (CFunction = 2 slots, Wasm = 4 slots).
+ for (int fixed_slots : {2, 3, 4, 5}) {
+ for (int spill_slots : {0, 1, 2, 3, 4}) {
+ for (int return_slots : {0, 1, 2, 3}) {
+ Zone zone(isolate->allocator(), ZONE_NAME);
+ Frame frame(fixed_slots, &zone);
+
+ for (int s = 0; s < spill_slots; ++s) {
+ frame.AllocateSpillSlot(kSystemPointerSize);
+ }
+ frame.EnsureReturnSlots(return_slots);
+
+ OptimizedCompilationInfo info(base::ArrayVector("test"), &zone,
+ CodeKind::FOR_TESTING);
+ CodeGenerator codegen(
+ &zone, &frame, &linkage, env.instructions(), &info, isolate,
+ std::optional<OsrHelper>(), kNoSourcePosition, nullptr,
+ AssemblerOptions::Default(isolate), Builtin::kNoBuiltinId, 0, 0);
+
+ // FinishFrame() has now run via CodeGenerator's constructor.
+ CHECK_EQ(0, frame.GetTotalFrameSlotCount() % 2);
+ CHECK_EQ(0, frame.GetReturnSlotCount() % 2);
+
+ CodeGeneratorTester::AssembleConstructFrameForTest(&codegen);
+ }
+ }
+ }
+}
+#endif
+
#if V8_ENABLE_WEBASSEMBLY
namespace {
@@ -1687,17 +1733,16 @@ TEST(Regress_1171759) {
OptimizedCompilationInfo info(base::ArrayVector("testing"),
handles.main_zone(), CodeKind::WASM_FUNCTION);
- DirectHandle<Code> code =
- Pipeline::GenerateCodeForTesting(
- &info, handles.main_isolate(), desc, m.graph(),
- AssemblerOptions::Default(handles.main_isolate()), m.ExportForTest())
- .ToHandleChecked();
+ wasm::WasmCompilationResult result = Pipeline::GenerateWasmCodeForTesting(
+ &info, handles.main_isolate(), desc, m.graph(),
+ AssemblerOptions::Default(handles.main_isolate()), m.ExportForTest());
+ CHECK(result.succeeded());
std::shared_ptr<wasm::NativeModule> module =
- AllocateNativeModule(handles.main_isolate(), code->instruction_size());
+ AllocateNativeModule(handles.main_isolate(), result.code_desc.instr_size);
wasm::WasmCodeRefScope wasm_code_ref_scope;
wasm::WasmCode* wasm_code =
- module->AddCodeForTesting(code, desc->signature_hash());
+ module->AddCodeForTesting(result, desc->signature_hash());
WasmCodePointer code_pointer =
wasm::GetProcessWideWasmCodePointerTable()->AllocateAndInitializeEntry(
wasm_code->instruction_start(), wasm_code->signature_hash());
@@ -1738,6 +1783,7 @@ TEST(Regress_1171759) {
wasm::GetProcessWideWasmCodePointerTable()->FreeEntry(code_pointer);
}
+
#endif // V8_ENABLE_WEBASSEMBLY
} // namespace compiler
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
index 912329d7ab9..22692e60198 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -80,9 +80,12 @@ class JSTypedLoweringTester : public HandleAndZoneScope,
Node* stack =
graph.NewNode(common.StateValues(0, SparseInputMask::Dense()));
+ FrameStateFunctionInfo const* function_info =
+ common.CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 0, 0, 0, {}, {});
Node* state_node = graph.NewNode(
common.FrameState(BytecodeOffset::None(),
- OutputFrameStateCombine::Ignore(), nullptr),
+ OutputFrameStateCombine::Ignore(), function_info),
parameters, locals, stack, context, UndefinedConstant(), graph.start());
return state_node;
diff --git a/deps/v8/test/cctest/compiler/test-multiple-return.cc b/deps/v8/test/cctest/compiler/test-multiple-return.cc
index 0cfab87f73c..2e2243ca3cd 100644
--- a/deps/v8/test/cctest/compiler/test-multiple-return.cc
+++ b/deps/v8/test/cctest/compiler/test-multiple-return.cc
@@ -166,18 +166,12 @@ void TestReturnMultipleValues(MachineType type, int min_count, int max_count) {
OptimizedCompilationInfo info(base::ArrayVector("testing"),
handles.main_zone(),
CodeKind::WASM_FUNCTION);
- DirectHandle<Code> code =
- Pipeline::GenerateCodeForTesting(
+ wasm::WasmCompilationResult wasm_result =
+ Pipeline::GenerateWasmCodeForTesting(
&info, handles.main_isolate(), desc, m.graph(),
AssemblerOptions::Default(handles.main_isolate()),
- m.ExportForTest())
- .ToHandleChecked();
-#ifdef ENABLE_DISASSEMBLER
- if (v8_flags.print_code) {
- StdoutStream os;
- code->Disassemble("multi_value", os, handles.main_isolate());
- }
-#endif
+ m.ExportForTest());
+ CHECK(wasm_result.succeeded());
const int a = 47, b = 12;
int expect = 0;
@@ -189,10 +183,16 @@ void TestReturnMultipleValues(MachineType type, int min_count, int max_count) {
}
std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
- handles.main_isolate(), code->instruction_size());
+ handles.main_isolate(), wasm_result.code_desc.instr_size);
wasm::WasmCodeRefScope wasm_code_ref_scope;
wasm::WasmCode* wasm_code =
- module->AddCodeForTesting(code, desc->signature_hash());
+ module->AddCodeForTesting(wasm_result, desc->signature_hash());
+#ifdef ENABLE_DISASSEMBLER
+ if (v8_flags.print_code) {
+ StdoutStream os;
+ wasm_code->Disassemble("multi_value", os);
+ }
+#endif
WasmCodePointer code_pointer =
wasm::GetProcessWideWasmCodePointerTable()
->AllocateAndInitializeEntry(wasm_code->instruction_start(),
@@ -287,18 +287,18 @@ void ReturnLastValue(MachineType type) {
OptimizedCompilationInfo info(base::ArrayVector("testing"),
handles.main_zone(), CodeKind::WASM_FUNCTION);
- DirectHandle<Code> code =
- Pipeline::GenerateCodeForTesting(
+ wasm::WasmCompilationResult wasm_result =
+ Pipeline::GenerateWasmCodeForTesting(
&info, handles.main_isolate(), desc, m.graph(),
AssemblerOptions::Default(handles.main_isolate()),
- m.ExportForTest())
- .ToHandleChecked();
+ m.ExportForTest());
+ CHECK(wasm_result.succeeded());
- std::shared_ptr<wasm::NativeModule> module =
- AllocateNativeModule(handles.main_isolate(), code->instruction_size());
+ std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
+ handles.main_isolate(), wasm_result.code_desc.instr_size);
wasm::WasmCodeRefScope wasm_code_ref_scope;
wasm::WasmCode* wasm_code =
- module->AddCodeForTesting(code, desc->signature_hash());
+ module->AddCodeForTesting(wasm_result, desc->signature_hash());
WasmCodePointer code_pointer =
wasm::GetProcessWideWasmCodePointerTable()->AllocateAndInitializeEntry(
wasm_code->instruction_start(), wasm_code->signature_hash());
@@ -358,18 +358,18 @@ void ReturnSumOfReturns(MachineType type) {
OptimizedCompilationInfo info(base::ArrayVector("testing"),
handles.main_zone(), CodeKind::WASM_FUNCTION);
- DirectHandle<Code> code =
- Pipeline::GenerateCodeForTesting(
+ wasm::WasmCompilationResult wasm_result =
+ Pipeline::GenerateWasmCodeForTesting(
&info, handles.main_isolate(), desc, m.graph(),
AssemblerOptions::Default(handles.main_isolate()),
- m.ExportForTest())
- .ToHandleChecked();
+ m.ExportForTest());
+ CHECK(wasm_result.succeeded());
- std::shared_ptr<wasm::NativeModule> module =
- AllocateNativeModule(handles.main_isolate(), code->instruction_size());
+ std::shared_ptr<wasm::NativeModule> module = AllocateNativeModule(
+ handles.main_isolate(), wasm_result.code_desc.instr_size);
wasm::WasmCodeRefScope wasm_code_ref_scope;
wasm::WasmCode* wasm_code =
- module->AddCodeForTesting(code, desc->signature_hash());
+ module->AddCodeForTesting(wasm_result, desc->signature_hash());
WasmCodePointer code_pointer =
wasm::GetProcessWideWasmCodePointerTable()->AllocateAndInitializeEntry(
wasm_code->instruction_start(), wasm_code->signature_hash());
diff --git a/deps/v8/test/cctest/heap/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h
index 8c5ab02339a..219cc501f27 100644
--- a/deps/v8/test/cctest/heap/heap-tester.h
+++ b/deps/v8/test/cctest/heap/heap-tester.h
@@ -47,8 +47,6 @@
V(TestSizeOfObjects) \
V(Regress10560) \
V(Regress538257) \
- V(Regress587004) \
- V(Regress589413) \
V(Regress658718) \
V(Regress777177) \
V(Regress779503) \
diff --git a/deps/v8/test/cctest/heap/heap-utils.cc b/deps/v8/test/cctest/heap/heap-utils.cc
index 0a3eb671e24..9d6ed0e71ef 100644
--- a/deps/v8/test/cctest/heap/heap-utils.cc
+++ b/deps/v8/test/cctest/heap/heap-utils.cc
@@ -484,7 +484,7 @@ ManualGCScope::ManualGCScope(Isolate* isolate)
// CppHeap concurrent marking has a dependency on concurrent marking.
v8_flags.cppheap_concurrent_marking = false;
- if (isolate_ && isolate_->heap()->cpp_heap()) {
+ if (isolate_) {
CppHeap::From(isolate_->heap()->cpp_heap())
->UpdateGCCapabilitiesFromFlagsForTesting();
}
@@ -501,7 +501,7 @@ ManualGCScope::~ManualGCScope() {
flag_detect_ineffective_gcs_near_heap_limit_;
v8_flags.cppheap_concurrent_marking = flag_cppheap_concurrent_marking_;
- if (isolate_ && isolate_->heap()->cpp_heap()) {
+ if (isolate_) {
CppHeap::From(isolate_->heap()->cpp_heap())
->UpdateGCCapabilitiesFromFlagsForTesting();
}
diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc
index 1d640d4b820..14c9ede39b9 100644
--- a/deps/v8/test/cctest/heap/test-heap.cc
+++ b/deps/v8/test/cctest/heap/test-heap.cc
@@ -1580,82 +1580,6 @@ TEST(MessageObjectLeak) {
CompileRun(test2);
}
-static void CheckEqualSharedFunctionInfos(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- CHECK(i::ValidateCallbackInfo(info));
- DirectHandle<Object> obj1 = v8::Utils::OpenDirectHandle(*info[0]);
- DirectHandle<Object> obj2 = v8::Utils::OpenDirectHandle(*info[1]);
- DirectHandle<JSFunction> fun1 = Cast<JSFunction>(obj1);
- DirectHandle<JSFunction> fun2 = Cast<JSFunction>(obj2);
- CHECK(fun1->shared() == fun2->shared());
-}
-
-static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& info) {
- CHECK(i::ValidateCallbackInfo(info));
- Isolate* isolate = CcTest::i_isolate();
- DirectHandle<Object> obj = v8::Utils::OpenDirectHandle(*info[0]);
- DirectHandle<JSFunction> fun = Cast<JSFunction>(obj);
- // Bytecode is code too.
- SharedFunctionInfo::DiscardCompiled(isolate,
- direct_handle(fun->shared(), isolate));
- fun->UpdateCode(isolate, *BUILTIN_CODE(isolate, CompileLazy));
- heap::InvokeMemoryReducingMajorGCs(CcTest::heap());
-}
-
-TEST(CanonicalSharedFunctionInfo) {
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
- global->Set(
- isolate, "check",
- v8::FunctionTemplate::New(isolate, CheckEqualSharedFunctionInfos));
- global->Set(isolate, "remove",
- v8::FunctionTemplate::New(isolate, RemoveCodeAndGC));
- v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
- v8::Context::Scope cscope(context);
- CompileRun(
- "function f() { return function g() {}; }"
- "var g1 = f();"
- "remove(f);"
- "var g2 = f();"
- "check(g1, g2);");
-
- CompileRun(
- "function f() { return (function() { return function g() {}; })(); }"
- "var g1 = f();"
- "remove(f);"
- "var g2 = f();"
- "check(g1, g2);");
-}
-
-TEST(ScriptIterator) {
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- LocalContext context;
-
- heap::InvokeMajorGC(heap);
-
- int script_count = 0;
- {
- HeapObjectIterator it(heap);
- for (Tagged<HeapObject> obj = it.Next(); !obj.is_null(); obj = it.Next()) {
- if (IsScript(obj)) script_count++;
- }
- }
-
- {
- Script::Iterator iterator(isolate);
- for (Tagged<Script> script = iterator.Next(); !script.is_null();
- script = iterator.Next()) {
- script_count--;
- }
- }
-
- CHECK_EQ(0, script_count);
-}
// This is the same as Factory::NewByteArray, except it doesn't retry on
// allocation failure.
@@ -1683,364 +1607,7 @@ bool HeapTester::CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes) {
AllocationOrigin::kRuntime);
}
-HEAP_TEST(Regress587004) {
- if (v8_flags.single_generation) return;
- ManualGCScope manual_gc_scope;
-#ifdef VERIFY_HEAP
- v8_flags.verify_heap = false;
-#endif
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- const int N = (kMaxRegularHeapObjectSize - OFFSET_OF_DATA_START(FixedArray)) /
- kTaggedSize;
- DirectHandle<FixedArray> array =
- factory->NewFixedArray(N, AllocationType::kOld);
- CHECK(heap->old_space()->Contains(*array));
- DirectHandle<Object> number = factory->NewHeapNumber(1.0);
- CHECK(HeapLayout::InYoungGeneration(*number));
- for (int i = 0; i < N; i++) {
- array->set(i, *number);
- }
- heap::InvokeMajorGC(heap);
- heap::SimulateFullSpace(heap->old_space());
- heap->RightTrimArray(*array, 1, N);
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- Tagged<ByteArray> byte_array;
- const uint32_t M = 256;
- // Don't allow old space expansion. The test works without this flag too,
- // but becomes very slow.
- heap->set_force_oom(true);
- while (
- AllocateByteArrayForTest(heap, M, AllocationType::kOld).To(&byte_array)) {
- for (uint32_t j = 0; j < M; j++) {
- byte_array->set(j, 0x31);
- }
- }
- // Re-enable old space expansion to avoid OOM crash.
- heap->set_force_oom(false);
- heap::InvokeMinorGC(heap);
-}
-
-HEAP_TEST(Regress589413) {
- if (!v8_flags.incremental_marking || v8_flags.stress_concurrent_allocation) {
- return;
- }
- v8_flags.stress_compaction = true;
- ManualGCScope manual_gc_scope;
- heap::ManualEvacuationCandidatesSelectionScope
- manual_evacuation_candidate_selection_scope(manual_gc_scope);
- v8_flags.parallel_compaction = false;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- // Get the heap in clean state.
- heap::InvokeMajorGC(heap);
- heap::InvokeMajorGC(heap);
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- // Fill the new space with byte arrays with elements looking like pointers.
- const uint32_t M = 256;
- Tagged<ByteArray> byte_array;
- NormalPage* young_page = nullptr;
- while (AllocateByteArrayForTest(heap, M, AllocationType::kYoung)
- .To(&byte_array)) {
- // Only allocate objects on one young page as a rough estimate on
- // how much memory can be promoted into the old generation.
- // Otherwise we would crash when forcing promotion of all young
- // live objects.
- if (!young_page) young_page = NormalPage::FromHeapObject(byte_array);
- if (NormalPage::FromHeapObject(byte_array) != young_page) break;
-
- for (uint32_t j = 0; j < M; j++) {
- byte_array->set(j, 0x31);
- }
- // Add the array in root set.
- handle(byte_array, isolate);
- }
- auto reset_oom = [](void* heap, size_t limit, size_t) -> size_t {
- reinterpret_cast<Heap*>(heap)->set_force_oom(false);
- return limit;
- };
- heap->AddNearHeapLimitCallback(reset_oom, heap);
-
- {
- // Ensure that incremental marking is not started unexpectedly.
- AlwaysAllocateScopeForTesting always_allocate(isolate->heap());
-
- // Make sure the byte arrays will be promoted on the next GC.
- heap::InvokeMinorGC(heap);
- // This number is close to large free list category threshold.
- const uint32_t N = 0x3EEE;
-
- std::vector<Tagged<FixedArray>> arrays;
- std::set<NormalPage*> pages;
- Tagged<FixedArray> array;
- // Fill all pages with fixed arrays.
- heap->set_force_oom(true);
- while (
- AllocateFixedArrayForTest(heap, N, AllocationType::kOld).To(&array)) {
- arrays.push_back(array);
- pages.insert(NormalPage::FromHeapObject(array));
- // Add the array in root set.
- handle(array, isolate);
- }
- heap->set_force_oom(false);
- size_t initial_pages = pages.size();
- // Expand and fill two pages with fixed array to ensure enough space both
- // the young objects and the evacuation candidate pages.
- while (
- AllocateFixedArrayForTest(heap, N, AllocationType::kOld).To(&array)) {
- arrays.push_back(array);
- pages.insert(NormalPage::FromHeapObject(array));
- // Add the array in root set.
- handle(array, isolate);
- // Do not expand anymore.
- if (pages.size() - initial_pages == 2) {
- heap->set_force_oom(true);
- }
- }
- // Expand and mark the new page as evacuation candidate.
- heap->set_force_oom(false);
- {
- DirectHandle<HeapObject> ec_obj =
- factory->NewFixedArray(5000, AllocationType::kOld);
- NormalPage* ec_page = NormalPage::FromHeapObject(*ec_obj);
- heap::ForceEvacuationCandidate(ec_page);
- // Make all arrays point to evacuation candidate so that
- // slots are recorded for them.
- for (size_t j = 0; j < arrays.size(); j++) {
- array = arrays[j];
- for (uint32_t i = 0; i < N; i++) {
- array->set(i, *ec_obj);
- }
- }
- }
- CHECK(heap->incremental_marking()->IsStopped());
- heap::SimulateIncrementalMarking(heap);
- for (size_t j = 0; j < arrays.size(); j++) {
- heap->RightTrimArray(arrays[j], 1, N);
- }
- }
-
- // Force allocation from the free list.
- heap->set_force_oom(true);
- heap::InvokeMajorGC(heap);
- heap->RemoveNearHeapLimitCallback(reset_oom, 0);
-}
-TEST(Regress598319) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- // This test ensures that no white objects can cross the progress bar of large
- // objects during incremental marking. It checks this by using Shift() during
- // incremental marking.
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- Isolate* isolate = heap->isolate();
-
- // The size of the array should be larger than kProgressBarScanningChunk.
- const uint32_t kNumberOfObjects =
- std::max(FixedArray::kMaxRegularLength + 1, 128 * KB);
-
- struct Arr {
- Arr(Isolate* isolate, uint32_t number_of_objects) {
- root = isolate->factory()->NewFixedArray(1, AllocationType::kOld);
- {
- // Temporary scope to avoid getting any other objects into the root set.
- v8::HandleScope new_scope(CcTest::isolate());
- DirectHandle<FixedArray> tmp = isolate->factory()->NewFixedArray(
- number_of_objects, AllocationType::kOld);
- root->set(0, *tmp);
- const uint32_t length = get()->length().value();
- for (uint32_t i = 0; i < length; i++) {
- tmp = isolate->factory()->NewFixedArray(100, AllocationType::kOld);
- get()->set(i, *tmp);
- }
- }
- global_root.Reset(CcTest::isolate(), Utils::ToLocal(Cast<Object>(root)));
- }
-
- Tagged<FixedArray> get() { return Cast<FixedArray>(root->get(0)); }
-
- Handle<FixedArray> root;
-
- // Store array in global as well to make it part of the root set when
- // starting incremental marking.
- v8::Global<Value> global_root;
- } arr(isolate, kNumberOfObjects);
-
- CHECK_EQ(arr.get()->length().value(), kNumberOfObjects);
- CHECK(heap->lo_space()->Contains(arr.get()));
- LargePage* page = LargePage::FromHeapObject(isolate, arr.get());
- CHECK_NOT_NULL(page);
-
- // GC to cleanup state
- heap::InvokeMajorGC(heap);
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
-
- CHECK(heap->lo_space()->Contains(arr.get()));
- IncrementalMarking* marking = heap->incremental_marking();
- MarkingState* marking_state = heap->marking_state();
- CHECK(marking_state->IsUnmarked(arr.get()));
-
- for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
- Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
- CHECK(marking_state->IsUnmarked(arr_value));
- }
-
- // Start incremental marking.
- CHECK(marking->IsMarking() || marking->IsStopped());
- if (marking->IsStopped()) {
- heap->StartIncrementalMarking(i::GCFlag::kNoFlags,
- i::GarbageCollectionReason::kTesting);
- }
- CHECK(marking->IsMarking());
-
- // Check that we have not marked the interesting array during root scanning.
- for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
- Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
- CHECK(marking_state->IsUnmarked(arr_value));
- }
-
- // Now we search for a state where we are in incremental marking and have
- // only partially marked the large object.
- static constexpr auto kSmallStepSize =
- v8::base::TimeDelta::FromMillisecondsD(0.1);
- static constexpr size_t kSmallMaxBytesToMark = 100;
- while (!marking->IsMajorMarkingComplete()) {
- marking->AdvanceForTesting(kSmallStepSize, kSmallMaxBytesToMark);
- MarkingProgressTracker& progress_tracker = page->marking_progress_tracker();
- if (progress_tracker.IsEnabled() &&
- progress_tracker.GetCurrentChunkForTesting() > 0) {
- CHECK_NE(progress_tracker.GetCurrentChunkForTesting(), arr.get()->Size());
- {
- // Shift by 1, effectively moving one white object across the progress
- // bar, meaning that we will miss marking it.
- v8::HandleScope new_scope(CcTest::isolate());
- DirectHandle<JSArray> js_array =
- isolate->factory()->NewJSArrayWithElements(
- DirectHandle<FixedArray>(arr.get(), isolate));
- js_array->GetElementsAccessor()->Shift(isolate, js_array);
- }
- break;
- }
- }
-
- SafepointScope safepoint_scope(heap->isolate(),
- kGlobalSafepointForSharedSpaceIsolate);
- MarkingBarrier::PublishAll(heap);
-
- // Finish marking with bigger steps to speed up test.
- static constexpr auto kLargeStepSize =
- v8::base::TimeDelta::FromMilliseconds(1000);
- while (!marking->IsMajorMarkingComplete()) {
- marking->AdvanceForTesting(kLargeStepSize);
- }
- CHECK(marking->IsMajorMarkingComplete());
-
- // All objects need to be black after marking. If a white object crossed the
- // progress bar, we would fail here.
- for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
- Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
- CHECK(HeapLayout::InReadOnlySpace(arr_value) ||
- marking_state->IsMarked(arr_value));
- }
-}
-
-DirectHandle<FixedArray> ShrinkArrayAndCheckSize(Heap* heap, int length) {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- // Make sure there is no garbage and the compilation cache is empty.
- for (int i = 0; i < 5; i++) {
- heap::InvokeMajorGC(heap);
- }
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- // Disable LAB, such that calculations with SizeOfObjects() and object size
- // are correct.
- heap->DisableInlineAllocation();
- size_t size_before_allocation = heap->SizeOfObjects();
- IndirectHandle<FixedArray> array(
- *heap->isolate()->factory()->NewFixedArray(length, AllocationType::kOld),
- heap->isolate());
- size_t size_after_allocation = heap->SizeOfObjects();
- CHECK_EQ(size_after_allocation, size_before_allocation + array->Size());
- array->RightTrim(heap->isolate(), 1);
- size_t size_after_shrinking = heap->SizeOfObjects();
- // Shrinking does not change the space size immediately.
- CHECK_EQ(size_after_allocation, size_after_shrinking);
- // GC and sweeping updates the size to account for shrinking.
- heap::InvokeMajorGC(heap);
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- intptr_t size_after_gc = heap->SizeOfObjects();
- CHECK_EQ(size_after_gc, size_before_allocation + array->Size());
- return array;
-}
-
-TEST(Regress609761) {
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- int length = kMaxRegularHeapObjectSize / kTaggedSize + 1;
- DirectHandle<FixedArray> array = ShrinkArrayAndCheckSize(heap, length);
- CHECK(heap->lo_space()->Contains(*array));
-}
-
-TEST(LiveBytes) {
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- DirectHandle<FixedArray> array = ShrinkArrayAndCheckSize(heap, 2000);
- CHECK(heap->old_space()->Contains(*array));
-}
-
-TEST(Regress615489) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- Isolate* isolate = heap->isolate();
- heap::InvokeMajorGC(heap);
-
- i::IncrementalMarking* marking = heap->incremental_marking();
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
- CHECK(marking->IsMarking() || marking->IsStopped());
- if (marking->IsStopped()) {
- heap->StartIncrementalMarking(i::GCFlag::kNoFlags,
- i::GarbageCollectionReason::kTesting);
- }
- CHECK(marking->IsMarking());
- CHECK(marking->black_allocation());
- {
- AlwaysAllocateScopeForTesting always_allocate(heap);
- v8::HandleScope inner(CcTest::isolate());
- isolate->factory()->NewFixedArray(500, AllocationType::kOld)->Size();
- }
- static constexpr auto kStepSize = v8::base::TimeDelta::FromMilliseconds(100);
- while (!marking->IsMajorMarkingComplete()) {
- marking->AdvanceForTesting(kStepSize);
- }
- CHECK(marking->IsMajorMarkingComplete());
- intptr_t size_before = heap->SizeOfObjects();
- heap::InvokeMajorGC(heap);
- intptr_t size_after = heap->SizeOfObjects();
- // Live size does not increase after garbage collection.
- CHECK_LE(size_after, size_before);
-}
class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
public:
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index 51a099b6478..77ea7955926 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -153,15 +153,15 @@ constexpr v8::ExternalPointerTypeTag kIntPointerTag = 12;
static void GetIntValue(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- int* value =
- static_cast<int*>(info.Data().As<v8::External>()->Value(kIntPointerTag));
+ int* value = static_cast<int*>(
+ info.DataV2().As<v8::External>()->Value(kIntPointerTag));
info.GetReturnValue().Set(v8_num(*value));
}
static void SetIntValue(Local<Name> property, Local<Value> value,
const v8::PropertyCallbackInfo<Boolean>& info) {
- int* field =
- static_cast<int*>(info.Data().As<v8::External>()->Value(kIntPointerTag));
+ int* field = static_cast<int*>(
+ info.DataV2().As<v8::External>()->Value(kIntPointerTag));
*field = value->Int32Value(info.GetIsolate()->GetCurrentContext()).FromJust();
}
@@ -350,17 +350,20 @@ static void CheckAccessorArgsCorrect(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
i::ValidateCallbackInfo(info);
CHECK(info.GetIsolate() == CcTest::isolate());
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<v8::Value>()
->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
.FromJust());
ApiTestFuzzer::Fuzz();
CHECK(info.GetIsolate() == CcTest::isolate());
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<v8::Value>()
->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
.FromJust());
CHECK(info.GetIsolate() == CcTest::isolate());
i::heap::InvokeMajorGC(CcTest::heap());
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<v8::Value>()
->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("data"))
.FromJust());
info.GetReturnValue().Set(17);
diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc
index 96821240ece..b2b29a1bcb4 100644
--- a/deps/v8/test/cctest/test-api-array-buffer.cc
+++ b/deps/v8/test/cctest/test-api-array-buffer.cc
@@ -4,6 +4,8 @@
#include <span>
+#include "include/cppgc/allocation.h"
+#include "include/v8-cppgc.h"
#include "src/api/api-inl.h"
#include "src/base/logging.h"
#include "src/base/strings.h"
@@ -1354,3 +1356,57 @@ TEST(SharedArrayBuffer_CopyArrayBufferBytes) {
CHECK_EQ(2, ab1->CopyArrayBufferBytes(0, 6, ab2, 2));
CHECK_EQ(0, std::memcmp(ab2->Data(), "1212", 4));
}
+
+TEST(ArrayBuffer_DetachCallback_NonWrapped) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ // Detaching an unwrapped ArrayBuffer should not trigger the callback.
+ isolate->SetArrayBufferDetachCallback(
+ [](v8::Isolate*, v8::Local<v8::ArrayBuffer>) { CHECK(false); });
+
+ auto unwrapped_ab = v8::ArrayBuffer::New(isolate, 16);
+ unwrapped_ab->Detach(v8::Local<v8::Value>()).Check();
+
+ isolate->SetArrayBufferDetachCallback(nullptr);
+}
+
+TEST(ArrayBuffer_DetachCallback_Wrapped) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ class Wrapper : public v8::Object::Wrappable {
+ public:
+ int detach_count = 0;
+
+ void Trace(cppgc::Visitor* visitor) const override {
+ v8::Object::Wrappable::Trace(visitor);
+ }
+ };
+
+ isolate->SetArrayBufferDetachCallback(
+ [](v8::Isolate* isolate, v8::Local<v8::ArrayBuffer> buffer) {
+ auto* wrapper =
+ v8::Object::Unwrap<i::kTagForTesting, Wrapper>(isolate, buffer);
+ CHECK_NOT_NULL(wrapper);
+ wrapper->detach_count++;
+ });
+
+ // Detaching a wrapped ArrayBuffer should trigger the callback once.
+ auto wrapped_ab = v8::ArrayBuffer::New(isolate, 16);
+ Wrapper* wrapper = cppgc::MakeGarbageCollected<Wrapper>(
+ isolate->GetCppHeap()->GetAllocationHandle());
+ v8::Object::Wrap<i::kTagForTesting>(
+ isolate, wrapped_ab, reinterpret_cast<v8::Object::Wrappable*>(wrapper));
+ wrapped_ab->Detach(v8::Local<v8::Value>()).Check();
+ CHECK_EQ(1, wrapper->detach_count);
+
+ // Detaching an already detached ArrayBuffer should not trigger the callback
+ // again.
+ wrapped_ab->Detach(v8::Local<v8::Value>()).Check();
+ CHECK_EQ(1, wrapper->detach_count);
+
+ isolate->SetArrayBufferDetachCallback(nullptr);
+}
diff --git a/deps/v8/test/cctest/test-api-incumbent.cc b/deps/v8/test/cctest/test-api-incumbent.cc
index 4fcdfab9398..9eed1b36d05 100644
--- a/deps/v8/test/cctest/test-api-incumbent.cc
+++ b/deps/v8/test/cctest/test-api-incumbent.cc
@@ -48,7 +48,7 @@ void FunctionWithIncumbentCheck(
IncumbentTestExpectations* expected =
reinterpret_cast<IncumbentTestExpectations*>(
- info.Data().As<External>()->Value(kIncumbentTestExpectationsTag));
+ info.DataV2().As<External>()->Value(kIncumbentTestExpectationsTag));
expected->call_count++;
diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc
index fef08bfaa21..452bc8dfa2d 100644
--- a/deps/v8/test/cctest/test-api-interceptors.cc
+++ b/deps/v8/test/cctest/test-api-interceptors.cc
@@ -20,6 +20,7 @@
using ::v8::Boolean;
using ::v8::Context;
+using ::v8::Data;
using ::v8::Function;
using ::v8::FunctionTemplate;
using ::v8::Local;
@@ -103,17 +104,17 @@ void SimpleSetterImpl(Local<String> name_str,
}
void SimpleGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
- Local<String> name_str = args.Data().As<String>();
+ Local<String> name_str = args.DataV2().As<Value>().As<String>();
SimpleGetterImpl(name_str, args);
}
void SimpleSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
- Local<String> name_str = info.Data().As<String>();
+ Local<String> name_str = info.DataV2().As<Value>().As<String>();
SimpleSetterImpl(name_str, info);
}
void SymbolGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
- Local<Name> name = info.Data().As<Name>();
+ Local<Name> name = info.DataV2().As<Value>().As<Name>();
CHECK(name->IsSymbol());
v8::Isolate* isolate = info.GetIsolate();
Local<Symbol> sym = name.As<Symbol>();
@@ -122,7 +123,7 @@ void SymbolGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
}
void SymbolSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
- Local<Name> name = info.Data().As<Name>();
+ Local<Name> name = info.DataV2().As<Value>().As<Name>();
CHECK(name->IsSymbol());
v8::Isolate* isolate = info.GetIsolate();
Local<Symbol> sym = name.As<Symbol>();
@@ -382,7 +383,8 @@ v8::Intercepted EchoNamedProperty(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("data")
- ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data())
+ ->Equals(info.GetIsolate()->GetCurrentContext(),
+ info.DataV2().As<v8::Value>())
.FromJust());
echo_named_call_count++;
info.GetReturnValue().Set(name);
@@ -1153,7 +1155,9 @@ v8::Intercepted InterceptorLoadICGetter(
v8::Isolate* isolate = CcTest::isolate();
CHECK_EQ(isolate, info.GetIsolate());
v8::Local<v8::Context> context = isolate->GetCurrentContext();
- CHECK(v8_str("data")->Equals(context, info.Data()).FromJust());
+ CHECK(v8_str("data")
+ ->Equals(context, info.DataV2().As<v8::Value>())
+ .FromJust());
CHECK(v8_str("x")->Equals(context, name).FromJust());
info.GetReturnValue().Set(v8::Integer::New(isolate, 42));
return v8::Intercepted::kYes;
@@ -3117,7 +3121,8 @@ v8::Intercepted EchoIndexedProperty(
uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_num(637)
- ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data())
+ ->Equals(info.GetIsolate()->GetCurrentContext(),
+ info.DataV2().As<v8::Value>())
.FromJust());
echo_indexed_call_count++;
info.GetReturnValue().Set(v8_num(index));
@@ -3718,7 +3723,7 @@ namespace {
v8::Intercepted XPropertyGetter(
Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- CHECK(info.Data()->IsUndefined());
+ CHECK(info.DataV2().As<v8::Value>()->IsUndefined());
info.GetReturnValue().Set(property);
return v8::Intercepted::kYes;
}
@@ -6381,9 +6386,9 @@ Local<Object> BuildWrappedObject(v8::Isolate* isolate, T* data) {
}
template <typename T>
-T* GetWrappedObject(Local<Value> data) {
+T* GetWrappedObject(Local<Data> data) {
return reinterpret_cast<T*>(
- Object::Cast(*data)->GetAlignedPointerFromInternalField(
+ data.As<Value>().As<Object>()->GetAlignedPointerFromInternalField(
0, kApiInterceptorTag));
}
@@ -6400,7 +6405,7 @@ struct ShouldInterceptData {
v8::Intercepted ShouldNamedGetterInterceptor(
Local<Name> name, const v8::PropertyCallbackInfo<Value>& info) {
CheckReturnValue(info, FUNCTION_ADDR(ShouldNamedGetterInterceptor));
- auto data = GetWrappedObject<ShouldInterceptData>(info.Data());
+ auto data = GetWrappedObject<ShouldInterceptData>(info.DataV2());
if (!data->should_intercept) return v8::Intercepted::kNo;
// Side effects are allowed only when the property is present or throws.
ApiTestFuzzer::Fuzz();
@@ -6411,7 +6416,7 @@ v8::Intercepted ShouldNamedGetterInterceptor(
v8::Intercepted ShouldIndexedGetterInterceptor(
uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
CheckReturnValue(info, FUNCTION_ADDR(ShouldIndexedGetterInterceptor));
- auto data = GetWrappedObject<ShouldInterceptData>(info.Data());
+ auto data = GetWrappedObject<ShouldInterceptData>(info.DataV2());
if (!data->should_intercept) return v8::Intercepted::kNo;
// Side effects are allowed only when the property is present or throws.
ApiTestFuzzer::Fuzz();
@@ -6423,7 +6428,7 @@ v8::Intercepted ShouldNamedSetterInterceptor(
Local<Name> name, Local<Value> value,
const v8::PropertyCallbackInfo<Boolean>& info) {
CheckReturnValue(info, FUNCTION_ADDR(ShouldNamedSetterInterceptor));
- auto data = GetWrappedObject<ShouldInterceptData>(info.Data());
+ auto data = GetWrappedObject<ShouldInterceptData>(info.DataV2());
if (!data->should_intercept) return v8::Intercepted::kNo;
// Side effects are allowed only when the property is present or throws.
ApiTestFuzzer::Fuzz();
@@ -7187,7 +7192,7 @@ constexpr v8::ExternalPointerTypeTag kCallsTag = 15;
v8::Intercepted Regress42204611_Getter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
std::vector<std::string>* calls = reinterpret_cast<std::vector<std::string>*>(
- info.Data().As<v8::External>()->Value(kCallsTag));
+ info.DataV2().As<v8::External>()->Value(kCallsTag));
calls->push_back("getter");
return v8::Intercepted::kNo;
@@ -7196,7 +7201,7 @@ v8::Intercepted Regress42204611_Setter(
Local<Name> name, Local<Value> value,
const v8::PropertyCallbackInfo<Boolean>& info) {
std::vector<std::string>* calls = reinterpret_cast<std::vector<std::string>*>(
- info.Data().As<v8::External>()->Value(kCallsTag));
+ info.DataV2().As<v8::External>()->Value(kCallsTag));
calls->push_back("setter");
return v8::Intercepted::kNo;
@@ -7205,7 +7210,7 @@ v8::Intercepted Regress42204611_Definer(
Local<Name> name, const v8::PropertyDescriptor& descriptor,
const v8::PropertyCallbackInfo<Boolean>& info) {
std::vector<std::string>* calls = reinterpret_cast<std::vector<std::string>*>(
- info.Data().As<v8::External>()->Value(kCallsTag));
+ info.DataV2().As<v8::External>()->Value(kCallsTag));
calls->push_back("definer");
return v8::Intercepted::kNo;
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 2c5d1dceebb..c98c4e2ecb3 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -75,6 +75,7 @@
#include "src/heap/incremental-marking.h"
#include "src/init/v8.h"
#include "src/logging/metrics.h"
+#include "src/objects/api-callbacks-inl.h"
#include "src/objects/feedback-vector-inl.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/hash-table-inl.h"
@@ -1567,7 +1568,7 @@ constexpr v8::ExternalPointerTypeTag kTestPtrTag = 16;
static void callback(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(i::ValidateCallbackInfo(args));
- void* ptr = v8::External::Cast(*args.Data())->Value(kTestPtrTag);
+ void* ptr = v8::External::Cast(*args.DataV2())->Value(kTestPtrTag);
CHECK_EQ(expected_ptr, ptr);
args.GetReturnValue().Set(true);
}
@@ -2924,7 +2925,7 @@ void SymbolAccessorGetterReturnsDefault(
v8::Isolate* isolate = info.GetIsolate();
Local<Symbol> sym = name.As<Symbol>();
if (sym->Description(isolate)->IsUndefined()) return;
- info.GetReturnValue().Set(info.Data());
+ info.GetReturnValue().Set(info.DataV2().As<Value>());
}
static void ThrowingSymbolAccessorGetter(
@@ -6873,7 +6874,8 @@ static void GetXValue(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
ApiTestFuzzer::Fuzz();
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<v8::Value>()
->Equals(CcTest::isolate()->GetCurrentContext(), v8_str("donut"))
.FromJust());
CHECK(name->Equals(CcTest::isolate()->GetCurrentContext(), v8_str("x"))
@@ -7172,7 +7174,8 @@ static void Get239Value(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
ApiTestFuzzer::Fuzz();
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<v8::Value>()
->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("donut"))
.FromJust());
CHECK(name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("239"))
@@ -7216,7 +7219,10 @@ static void SetXValue(Local<Name> name, Local<Value> value,
CHECK(i::ValidateCallbackInfo(info));
Local<Context> context = info.GetIsolate()->GetCurrentContext();
CHECK(value->Equals(context, v8_num(4)).FromJust());
- CHECK(info.Data()->Equals(context, v8_str("donut")).FromJust());
+ CHECK(info.DataV2()
+ .As<v8::Value>()
+ ->Equals(context, v8_str("donut"))
+ .FromJust());
CHECK(name->Equals(context, v8_str("x")).FromJust());
CHECK(xValue.IsEmpty());
xValue.Reset(info.GetIsolate(), value);
@@ -8025,12 +8031,12 @@ static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.IsConstructCall()) {
CHECK(args.This()
->Set(args.GetIsolate()->GetCurrentContext(), v8_str("data"),
- args.Data())
+ args.DataV2().As<Value>())
.FromJust());
args.GetReturnValue().SetNull();
return;
}
- args.GetReturnValue().Set(args.Data());
+ args.GetReturnValue().Set(args.DataV2().As<Value>());
}
@@ -12123,7 +12129,7 @@ v8::Intercepted InterceptorCallICFastApi(
// The request is not intercepted so don't call ApiTestFuzzer::Fuzz() here.
CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi));
int* call_count = reinterpret_cast<int*>(
- v8::External::Cast(*info.Data())->Value(kIntPointerTag));
+ v8::External::Cast(*info.DataV2())->Value(kIntPointerTag));
++(*call_count);
if ((*call_count) % 20 == 0) {
i::heap::InvokeMajorGC(CcTest::heap());
@@ -12141,7 +12147,8 @@ void FastApiCallback_TrivialSignature(
CHECK(info.This()
->Equals(isolate->GetCurrentContext(), info.This())
.FromJust());
- CHECK(info.Data()
+ CHECK(info.DataV2()
+ .As<Value>()
->Equals(isolate->GetCurrentContext(), v8_str("method_data"))
.FromJust());
info.GetReturnValue().Set(
@@ -22121,7 +22128,7 @@ class RequestInterruptTestBase {
const v8::FunctionCallbackInfo<Value>& info) {
RequestInterruptTestBase* test =
reinterpret_cast<RequestInterruptTestBase*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
info.GetReturnValue().Set(test->ShouldContinue());
}
@@ -22240,7 +22247,7 @@ class RequestInterruptTestWithNativeAccessor
CHECK(i::ValidateCallbackInfo(info));
RequestInterruptTestBase* test =
reinterpret_cast<RequestInterruptTestBase*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
info.GetReturnValue().Set(test->ShouldContinue());
}
};
@@ -22324,7 +22331,7 @@ class RequestInterruptTestWithMathAbs
RequestInterruptTestBase* test =
reinterpret_cast<RequestInterruptTestBase*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
test->WakeUpInterruptor();
}
@@ -22332,7 +22339,7 @@ class RequestInterruptTestWithMathAbs
const v8::FunctionCallbackInfo<Value>& info) {
RequestInterruptTestBase* test =
reinterpret_cast<RequestInterruptTestBase*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
info.GetReturnValue().Set(test->should_continue());
}
};
@@ -22411,7 +22418,7 @@ class RequestInterruptTestWithCppIterator
const v8::FunctionCallbackInfo<v8::Value>& info) {
RequestInterruptTestWithCppIterator* test =
reinterpret_cast<RequestInterruptTestWithCppIterator*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
v8::Isolate* isolate = info.GetIsolate();
Local<v8::ObjectTemplate> tmpl = test->iterator_template_.Get(isolate);
Local<v8::Object> iterator =
@@ -22423,7 +22430,7 @@ class RequestInterruptTestWithCppIterator
const v8::FunctionCallbackInfo<v8::Value>& info) {
RequestInterruptTestWithCppIterator* test =
reinterpret_cast<RequestInterruptTestWithCppIterator*>(
- info.Data().As<v8::External>()->Value(kTestPtrTag));
+ info.DataV2().As<v8::External>()->Value(kTestPtrTag));
v8::Isolate* isolate = info.GetIsolate();
Local<v8::Context> context = isolate->GetCurrentContext();
@@ -22537,9 +22544,10 @@ TEST(RequestInterruptDisallowsJavascript) {
static v8::Global<Value> function_new_expected_env_global;
static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
- CHECK(function_new_expected_env_global.Get(isolate)
- ->Equals(isolate->GetCurrentContext(), info.Data())
- .FromJust());
+ CHECK(
+ function_new_expected_env_global.Get(isolate)
+ ->Equals(isolate->GetCurrentContext(), info.DataV2().As<v8::Value>())
+ .FromJust());
info.GetReturnValue().Set(17);
}
@@ -22781,7 +22789,7 @@ class ApiCallOptimizationChecker {
static void OptimizationCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
- CHECK_EQ(data, info.Data());
+ CHECK_EQ(data, info.DataV2().As<Value>().As<Object>());
CHECK_EQ(receiver, info.This());
if (info.Length() == 1) {
CHECK(v8_num(1)
@@ -28829,8 +28837,11 @@ struct BasicApiChecker {
static Ret FastCallback(v8::Local<v8::Object> receiver, Value argument,
v8::FastApiCallbackOptions& options) {
// TODO(mslekova): Refactor the data checking.
- CHECK(options.data->IsNumber());
- CHECK_EQ(Local<v8::Number>::Cast(options.data)->Value(), 42.5);
+ v8::Local<v8::Data> data = options.DataV2();
+ CHECK(data->IsValue());
+ v8::Local<v8::Value> value = data.As<v8::Value>();
+ CHECK(value->IsNumber());
+ CHECK_EQ(Local<v8::Number>::Cast(value)->Value(), 42.5);
return Impl::FastCallback(receiver, argument, options);
}
static Ret FastCallbackNoOptions(v8::Local<v8::Object> receiver,
@@ -30845,10 +30856,19 @@ TEST(CodeLikeFunction) {
isolate->SetModifyCodeGenerationFromStringsCallback(
[](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
- return {true, v8_str("(function anonymous(\n) {\nreturn 7;\n})\n")};
+ // This callback runs twice here. First for the CodeLike argument
+ // itself, where source is an object, and it should reply with just the
+ // function body. Second for the fully assembled function source, since
+ // codegen is disabled and V8 double checks the final result, where
+ // source is a string, and it should reply with a complete function
+ // instead of just a body fragment.
+ if (source->IsString()) {
+ return {true, v8_str("(function anonymous(\n) {\nreturn 9;\n})\n")};
+ }
+ return {true, v8_str("return 9;")};
});
- ExpectInt32("new Function(new Other())()", 7);
- ExpectInt32("new Function(new CodeLike())()", 7);
+ ExpectInt32("new Function(new Other())()", 9);
+ ExpectInt32("new Function(new CodeLike())()", 9);
// Modify callback always disallows:
isolate->SetModifyCodeGenerationFromStringsCallback(
@@ -30866,10 +30886,271 @@ TEST(CodeLikeFunction) {
bool ok = is_code_like ||
(source->IsObject() && source.As<v8::Object>()->IsCodeLike(
v8::Isolate::GetCurrent()));
- return {ok, v8_str("(function anonymous(\n) {\nreturn 7;\n})\n")};
+ if (source->IsString()) {
+ return {ok, v8_str("(function anonymous(\n) {\nreturn 9;\n})\n")};
+ }
+ return {ok, v8_str("return 9;")};
});
CHECK(CompileRun("new Function(new Other())()").IsEmpty());
- ExpectInt32("new Function(new CodeLike())()", 7);
+ ExpectInt32("new Function(new CodeLike())()", 9);
+}
+
+TEST(CodeLikeFunctionToStringNotCalledWhenReplaced) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int to_string_call_count = 0;
+ to_string_call_count = 0;
+
+ // CodeLike object with a counting toString() method.
+ auto counting_to_string = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ to_string_call_count++;
+ info.GetReturnValue().Set(v8_str("this should never run"));
+ });
+ SetupCodeLike(&env, "CodeLike", counting_to_string, true);
+
+ // Callback returns a replacement, so toString() should never be called.
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ return {true, v8_str("return 9;")};
+ });
+
+ ExpectInt32("new Function(new CodeLike())()", 9);
+ CHECK_EQ(0, to_string_call_count);
+}
+
+TEST(CodeLikeFunctionToStringIsFallback) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int to_string_call_count = 0;
+ to_string_call_count = 0;
+
+ auto counting_string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ to_string_call_count++;
+ info.GetReturnValue().Set(v8_str("return 99;"));
+ });
+ SetupCodeLike(&env, "CodeLike", counting_string_fn, true);
+
+ // Callback allows codegen but supplies no replacement -> ToString() fallback
+ // runs.
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ return {true, v8::Local<v8::String>()};
+ });
+ ExpectInt32("new Function(new CodeLike())()", 99);
+ CHECK_EQ(1, to_string_call_count);
+
+ // Callback supplies a replacement -> ToString() must never run.
+ to_string_call_count = 0;
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ return {true, v8_str("return 42;")};
+ });
+ ExpectInt32("new Function(new CodeLike())()", 42);
+ CHECK_EQ(0, to_string_call_count);
+}
+
+TEST(CodeLikeFunctionCallbackSkippedOnAssembledSourceWhenCodegenAllowed) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ callback_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ info.GetReturnValue().Set(v8_str("return 4;"));
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {true, v8::Local<v8::String>()}; // fall back to ToString()
+ });
+
+ ExpectInt32("new Function(new CodeLike())()", 4);
+ // Codegen-from-strings is allowed by default, so
+ // ValidateDynamicCompilationSource's fast path returns the assembled
+ // String source directly without consulting the callback again — this
+ // is unrelated to per-argument consultation, it's the pre-existing
+ // behavior for the common (non-restricted) case.
+ CHECK_EQ(1, callback_call_count);
+}
+
+TEST(CodeLikeFunctionCallbackCalledOncePerCodeLikeArgument) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ static int string_fn_call_count = 0;
+ callback_call_count = 0;
+ string_fn_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ string_fn_call_count++;
+ // First CodeLike stringifies as the parameter, second as the body.
+ info.GetReturnValue().Set(
+ string_fn_call_count == 1 ? v8_str("a") : v8_str("return a;"));
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {true, v8::Local<v8::String>()}; // fall back to ToString()
+ });
+
+ ExpectInt32("new Function(new CodeLike(), new CodeLike())(9)", 9);
+ CHECK_EQ(2, callback_call_count);
+ CHECK_EQ(2, string_fn_call_count);
+}
+
+TEST(CodeLikeFunctionCallbackCalledOnlyForCodeLikeArgument) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ callback_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ info.GetReturnValue().Set(v8_str("return a;"));
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {true, v8::Local<v8::String>()}; // fall back to ToString()
+ });
+
+ // "a" is a plain string parameter and only the CodeLike body should reach
+ // the callback.
+ ExpectInt32("new Function('a', new CodeLike())(9)", 9);
+ CHECK_EQ(1, callback_call_count);
+}
+
+TEST(CodeLikeFunctionCallbackRejectionStopsArgumentConversion) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ static int to_string_call_count = 0;
+ callback_call_count = 0;
+ to_string_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ to_string_call_count++;
+ info.GetReturnValue().Set(v8_str("arg"));
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {false, v8::Local<v8::String>()};
+ });
+
+ // The callback rejects the first argument, before it or later arguments are
+ // converted with ToString().
+ CompileRun(
+ "var caught;"
+ "try {"
+ " new Function(new CodeLike(), new CodeLike(), new CodeLike());"
+ "} catch (e) {"
+ " caught = e;"
+ "}");
+ ExpectTrue("caught instanceof EvalError");
+ CHECK_EQ(1, callback_call_count);
+ CHECK_EQ(0, to_string_call_count);
+}
+
+TEST(CodeLikeOtherDynamicFunctionConstructorsUseCallback) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ callback_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ info.GetReturnValue().Set(v8_str("return 1;"));
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {true, v8::Local<v8::String>()};
+ });
+
+ CHECK(!CompileRun("new (function*() {}).constructor(new CodeLike());"
+ "new (async function() {}).constructor(new CodeLike());"
+ "new (async function*() {}).constructor(new CodeLike());")
+ .IsEmpty());
+ CHECK_EQ(3, callback_call_count);
+}
+
+TEST(CodeLikeFunctionMixedParameterList) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+
+ static int callback_call_count = 0;
+ static int to_string_call_count = 0;
+ callback_call_count = 0;
+ to_string_call_count = 0;
+
+ auto string_fn = v8::FunctionTemplate::New(
+ isolate, [](const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ to_string_call_count++;
+ if (to_string_call_count == 1) {
+ info.GetReturnValue().Set(v8_str("a"));
+ } else {
+ info.GetReturnValue().Set(v8_str("return a + b;"));
+ }
+ });
+ SetupCodeLike(&env, "CodeLike", string_fn, true);
+
+ isolate->SetModifyCodeGenerationFromStringsCallback(
+ [](v8::Local<v8::Context> context, v8::Local<v8::Value> source,
+ bool is_code_like) -> v8::ModifyCodeGenerationFromStringsResult {
+ callback_call_count++;
+ return {true, v8::Local<v8::String>()};
+ });
+
+ ExpectInt32("new Function(new CodeLike(), 'b', new CodeLike())(4, 5)", 9);
+ CHECK_EQ(2, callback_call_count);
+ CHECK_EQ(2, to_string_call_count);
}
namespace {
@@ -31658,7 +31939,7 @@ namespace {
v8::Local<v8::Value> GetContinuationPreservedEmbedderDataAsValue(
v8::Isolate* isolate) {
- v8::Local<v8::Data> data = isolate->GetContinuationPreservedEmbedderDataV2();
+ v8::Local<v8::Data> data = isolate->GetContinuationPreservedEmbedderData();
CHECK(data->IsValue());
return v8::Local<Value>::Cast(data);
}
@@ -31680,7 +31961,7 @@ TEST(ContinuationPreservedEmbedderData) {
Local<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(context.local()).ToLocalChecked();
- isolate->SetContinuationPreservedEmbedderDataV2(v8_str("foo"));
+ isolate->SetContinuationPreservedEmbedderData(v8_str("foo"));
v8::Local<v8::Function> get_isolate_preserved_data =
v8::Function::New(context.local(), GetIsolatePreservedContinuationData,
@@ -31691,7 +31972,7 @@ TEST(ContinuationPreservedEmbedderData) {
->Then(context.local(), get_isolate_preserved_data)
.ToLocalChecked();
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Undefined(isolate));
+ isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate));
resolver->Resolve(context.local(), v8::Undefined(isolate)).FromJust();
isolate->PerformMicrotaskCheckpoint();
@@ -31718,7 +31999,7 @@ TEST(ContinuationPreservedEmbedderDataClearedAndRestored) {
resolver->GetPromise()
->Then(context.local(), get_isolate_preserved_data)
.ToLocalChecked();
- isolate->SetContinuationPreservedEmbedderDataV2(v8_str("foo"));
+ isolate->SetContinuationPreservedEmbedderData(v8_str("foo"));
resolver->Resolve(context.local(), v8::Undefined(isolate)).FromJust();
isolate->PerformMicrotaskCheckpoint();
CHECK(p1->Result()->IsUndefined());
@@ -31748,11 +32029,11 @@ TEST(EnqueMicrotaskContinuationPreservedEmbedderData_CallbackTask) {
v8::Isolate* isolate = env.isolate();
v8::HandleScope scope(isolate);
- isolate->SetContinuationPreservedEmbedderDataV2(v8_str("foo"));
+ isolate->SetContinuationPreservedEmbedderData(v8_str("foo"));
env.local()->GetMicrotaskQueue()->EnqueueMicrotask(
isolate, &CallbackTaskMicrotask,
v8::External::New(isolate, isolate, v8::kExternalPointerTypeTagDefault));
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Undefined(isolate));
+ isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate));
isolate->PerformMicrotaskCheckpoint();
CHECK(did_callback_microtask_run);
@@ -31775,11 +32056,11 @@ TEST(EnqueMicrotaskContinuationPreservedEmbedderData_CallableTask) {
v8::Isolate* isolate = env.isolate();
v8::HandleScope scope(isolate);
- isolate->SetContinuationPreservedEmbedderDataV2(v8_str("foo"));
+ isolate->SetContinuationPreservedEmbedderData(v8_str("foo"));
env.local()->GetMicrotaskQueue()->EnqueueMicrotask(
env.isolate(),
Function::New(env.local(), CallableTaskMicrotask).ToLocalChecked());
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Undefined(isolate));
+ isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate));
isolate->PerformMicrotaskCheckpoint();
CHECK(did_callable_microtask_run);
@@ -31817,9 +32098,9 @@ TEST(ContinuationPreservedEmbedderData_Thenable) {
Local<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(env.local()).ToLocalChecked();
- isolate->SetContinuationPreservedEmbedderDataV2(v8_str("foo"));
+ isolate->SetContinuationPreservedEmbedderData(v8_str("foo"));
resolver->Resolve(env.local(), result).FromJust();
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Undefined(isolate));
+ isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate));
isolate->PerformMicrotaskCheckpoint();
CHECK(did_thenable_callback_run);
@@ -31830,17 +32111,17 @@ TEST(ContinuationPreservedEmbedderData_Empty) {
v8::Isolate* isolate = context.isolate();
v8::HandleScope scope(isolate);
- v8::Local<v8::Data> data = isolate->GetContinuationPreservedEmbedderDataV2();
+ v8::Local<v8::Data> data = isolate->GetContinuationPreservedEmbedderData();
CHECK(data->IsValue());
CHECK(Local<Value>::Cast(data)->IsUndefined());
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Local<v8::Data>());
- data = isolate->GetContinuationPreservedEmbedderDataV2();
+ isolate->SetContinuationPreservedEmbedderData(v8::Local<v8::Data>());
+ data = isolate->GetContinuationPreservedEmbedderData();
CHECK(data->IsValue());
CHECK(Local<Value>::Cast(data)->IsUndefined());
- isolate->SetContinuationPreservedEmbedderDataV2(v8::Undefined(isolate));
- data = isolate->GetContinuationPreservedEmbedderDataV2();
+ isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate));
+ data = isolate->GetContinuationPreservedEmbedderData();
CHECK(data->IsValue());
CHECK(Local<Value>::Cast(data)->IsUndefined());
}
@@ -32004,9 +32285,36 @@ TEST(LocalCasts) {
class TestGarbagedCollectedData
: public cppgc::GarbageCollected<TestGarbagedCollectedData> {
public:
+ void MarkUsed() { was_used_ = true; }
+ bool was_used() const { return was_used_; }
void Trace(cppgc::Visitor*) const {}
+
+ private:
+ bool was_used_ = false;
};
+void ReadCppHeapExternalCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Local<v8::Data> data = info.DataV2();
+ CHECK(data->IsCppHeapExternal());
+ v8::Local<v8::CppHeapExternal>::Cast(data)
+ ->Value<TestGarbagedCollectedData>(
+ info.GetIsolate(),
+ v8::CppHeapPointerTagRange(i::kTagForTesting, i::kTagForTesting))
+ ->MarkUsed();
+}
+
+void ReadCppHeapExternalPropertyCallback(
+ v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ v8::Local<v8::Data> data = info.DataV2();
+ CHECK(data->IsCppHeapExternal());
+ v8::Local<v8::CppHeapExternal>::Cast(data)
+ ->Value<TestGarbagedCollectedData>(
+ info.GetIsolate(),
+ v8::CppHeapPointerTagRange(i::kTagForTesting, i::kTagForTesting))
+ ->MarkUsed();
+}
+
class GCedWithCppHeapExternalJSRef
: public cppgc::GarbageCollected<GCedWithCppHeapExternalJSRef> {
public:
@@ -32015,8 +32323,8 @@ class GCedWithCppHeapExternalJSRef
: isolate_(isolate) {
v8::HandleScope scope(isolate_);
v8::Local<v8::CppHeapExternal> external =
- v8::CppHeapExternal::New<TestGarbagedCollectedData>(
- isolate, data, v8::CppHeapPointerTag::kTagForTesting);
+ v8::CppHeapExternal::New<TestGarbagedCollectedData>(isolate, data,
+ i::kTagForTesting);
v8_cpp_heap_external_.Reset(isolate_, external);
}
@@ -32027,8 +32335,7 @@ class GCedWithCppHeapExternalJSRef
auto external = v8::Local<v8::CppHeapExternal>::Cast(data);
return external->Value<TestGarbagedCollectedData>(
isolate_,
- v8::CppHeapPointerTagRange(v8::CppHeapPointerTag::kTagForTesting,
- v8::CppHeapPointerTag::kTagForTesting));
+ v8::CppHeapPointerTagRange(i::kTagForTesting, i::kTagForTesting));
}
void Trace(cppgc::Visitor* v) const { v->Trace(v8_cpp_heap_external_); }
@@ -32083,7 +32390,7 @@ TEST(CppHeapExternal) {
isolate->Dispose();
}
-TEST(ContinuationPreservedEmbedderDataV2_CppHeapExternal) {
+TEST(ContinuationPreservedEmbedderData_CppHeapExternal) {
v8::Isolate::CreateParams create_params = CreateTestParams();
create_params.cpp_heap =
v8::CppHeap::Create(::v8::internal::V8::GetCurrentPlatform(),
@@ -32100,18 +32407,17 @@ TEST(ContinuationPreservedEmbedderDataV2_CppHeapExternal) {
cpp_heap->GetAllocationHandle()));
v8::Local<v8::CppHeapExternal> external =
v8::CppHeapExternal::New<TestGarbagedCollectedData>(
- isolate, cpp_object.Get(), v8::CppHeapPointerTag::kTagForTesting);
- isolate->SetContinuationPreservedEmbedderDataV2(external);
+ isolate, cpp_object.Get(), i::kTagForTesting);
+ isolate->SetContinuationPreservedEmbedderData(external);
v8::Local<v8::Data> result =
- isolate->GetContinuationPreservedEmbedderDataV2();
+ isolate->GetContinuationPreservedEmbedderData();
CHECK(result->IsCppHeapExternal());
TestGarbagedCollectedData* data =
v8::Local<v8::CppHeapExternal>::Cast(result)
->Value<TestGarbagedCollectedData>(
- isolate, v8::CppHeapPointerTagRange(
- v8::CppHeapPointerTag::kTagForTesting,
- v8::CppHeapPointerTag::kTagForTesting));
+ isolate, v8::CppHeapPointerTagRange(i::kTagForTesting,
+ i::kTagForTesting));
CHECK_EQ(data, cpp_object.Get());
}
@@ -32140,38 +32446,153 @@ TEST(EmbedderDataAlignedPointers_CppHeapPointer) {
// Null pointer test.
(*env)->SetAlignedPointerInEmbedderData(
- 0, static_cast<TestGarbagedCollectedData*>(nullptr),
- v8::CppHeapPointerTag::kTagForTesting);
+ 0, static_cast<TestGarbagedCollectedData*>(nullptr), i::kTagForTesting);
CHECK_EQ(
nullptr,
(*env)->GetAlignedPointerFromEmbedderData<TestGarbagedCollectedData>(
- isolate, 0, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 0, i::kTagForTesting));
CHECK_EQ(nullptr, obj->GetAlignedPointerFromEmbedderDataInCreationContext(
- isolate, 0, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 0, i::kTagForTesting));
// Valid cppgc object test.
- (*env)->SetAlignedPointerInEmbedderData(
- 1, cpp_object.Get(), v8::CppHeapPointerTag::kTagForTesting);
+ (*env)->SetAlignedPointerInEmbedderData(1, cpp_object.Get(),
+ i::kTagForTesting);
CHECK_EQ(
cpp_object.Get(),
(*env)->GetAlignedPointerFromEmbedderData<TestGarbagedCollectedData>(
- isolate, 1, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 1, i::kTagForTesting));
CHECK_EQ(cpp_object.Get(),
obj->GetAlignedPointerFromEmbedderDataInCreationContext(
- isolate, 1, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 1, i::kTagForTesting));
// Detached global proxy test.
v8::Local<v8::Object> global_obj = env->Global();
- (*env)->SetAlignedPointerInEmbedderData(
- 2, cpp_object.Get(), v8::CppHeapPointerTag::kTagForTesting);
+ (*env)->SetAlignedPointerInEmbedderData(2, cpp_object.Get(),
+ i::kTagForTesting);
CHECK_EQ(cpp_object.Get(),
global_obj->GetAlignedPointerFromEmbedderDataInCreationContext(
- isolate, 2, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 2, i::kTagForTesting));
env->DetachGlobal();
CHECK_EQ(cpp_object.Get(),
global_obj->GetAlignedPointerFromEmbedderDataInCreationContext(
- isolate, 2, v8::CppHeapPointerTag::kTagForTesting));
+ isolate, 2, i::kTagForTesting));
+ }
+
+ isolate->Exit();
+ isolate->Dispose();
+}
+
+TEST(FunctionTemplateCallbackDataV2_CppHeapExternal) {
+ v8::Isolate::CreateParams create_params = CreateTestParams();
+ create_params.cpp_heap =
+ v8::CppHeap::Create(::v8::internal::V8::GetCurrentPlatform(),
+ v8::CppHeapCreateParams({}))
+ .release();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ isolate->Enter();
+ v8::CppHeap* cpp_heap = isolate->GetCppHeap();
+ i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
+
+ {
+ LocalContext env(isolate);
+ v8::Global<v8::Function> function;
+ cppgc::WeakPersistent<TestGarbagedCollectedData> cpp_object(
+ cppgc::MakeGarbageCollected<TestGarbagedCollectedData>(
+ cpp_heap->GetAllocationHandle()));
+
+ {
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::CppHeapExternal> external =
+ v8::CppHeapExternal::New<TestGarbagedCollectedData>(
+ isolate, cpp_object.Get(), i::kTagForTesting);
+ v8::Local<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(isolate);
+ function_template->SetCallHandler(ReadCppHeapExternalCallback, external);
+ function.Reset(
+ isolate,
+ function_template->GetFunction(env.local()).ToLocalChecked());
+ }
+
+ {
+ i::EmbedderStackStateScope stack_scope(
+ heap, i::EmbedderStackStateOrigin::kExplicitInvocation,
+ v8::StackState::kNoHeapPointers);
+ i::heap::InvokeMajorGC(heap);
+ }
+ CHECK(cpp_object.Get());
+
+ {
+ v8::HandleScope scope(isolate);
+ CHECK(!function.Get(isolate)
+ ->Call(env.local(), v8::Undefined(isolate), 0, nullptr)
+ .IsEmpty());
+ }
+ CHECK(cpp_object->was_used());
+ function.Reset();
+ }
+
+ isolate->Exit();
+ isolate->Dispose();
+}
+
+TEST(PropertyCallbackInfoDataV2_CppHeapExternal) {
+ v8::Isolate::CreateParams create_params = CreateTestParams();
+ create_params.cpp_heap =
+ v8::CppHeap::Create(::v8::internal::V8::GetCurrentPlatform(),
+ v8::CppHeapCreateParams({}))
+ .release();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ isolate->Enter();
+ v8::CppHeap* cpp_heap = isolate->GetCppHeap();
+ i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
+
+ {
+ LocalContext env(isolate);
+ v8::Global<v8::Object> object;
+ cppgc::WeakPersistent<TestGarbagedCollectedData> cpp_object(
+ cppgc::MakeGarbageCollected<TestGarbagedCollectedData>(
+ cpp_heap->GetAllocationHandle()));
+
+ {
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Name> name = v8_str("property");
+ v8::Local<v8::Object> local_object = v8::Object::New(isolate);
+ CHECK(local_object
+ ->SetNativeDataProperty(env.local(), name,
+ ReadCppHeapExternalPropertyCallback)
+ .FromJust());
+
+ v8::Local<v8::CppHeapExternal> external =
+ v8::CppHeapExternal::New<TestGarbagedCollectedData>(
+ isolate, cpp_object.Get(), i::kTagForTesting);
+ // Keep producer inputs Value-typed until the output migration completes.
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::LookupIterator it(i_isolate,
+ v8::Utils::OpenDirectHandle(*local_object),
+ v8::Utils::OpenDirectHandle(*name),
+ i::LookupIterator::OWN_SKIP_INTERCEPTOR);
+ CHECK_EQ(i::LookupIterator::ACCESSOR, it.state());
+ i::Cast<i::AccessorInfo>(it.GetAccessors())
+ ->set_data(*v8::Utils::OpenDirectHandle(*external));
+ object.Reset(isolate, local_object);
+ }
+
+ {
+ i::EmbedderStackStateScope stack_scope(
+ heap, i::EmbedderStackStateOrigin::kExplicitInvocation,
+ v8::StackState::kNoHeapPointers);
+ i::heap::InvokeMajorGC(heap);
+ }
+ CHECK(cpp_object.Get());
+
+ {
+ v8::HandleScope scope(isolate);
+ CHECK(
+ !object.Get(isolate)->Get(env.local(), v8_str("property")).IsEmpty());
+ }
+ CHECK(cpp_object->was_used());
+ object.Reset();
}
isolate->Exit();
diff --git a/deps/v8/test/cctest/test-api.h b/deps/v8/test/cctest/test-api.h
index 0c3ee7012bd..78b9b203a34 100644
--- a/deps/v8/test/cctest/test-api.h
+++ b/deps/v8/test/cctest/test-api.h
@@ -279,8 +279,13 @@ static v8::Local<v8::External> MakeData(v8::Isolate* isolate, void* pointer) {
template <typename T, typename TCallbackInfo>
static T* GetData(const TCallbackInfo& info) {
USE(MakeData);
- return reinterpret_cast<T*>(
- v8::External::Cast(*info.Data())->Value(kTestConfigTag));
+ v8::Local<v8::Data> data;
+ if constexpr (requires { info.DataV2(); }) {
+ data = info.DataV2();
+ } else {
+ data = info.Data();
+ }
+ return reinterpret_cast<T*>(v8::External::Cast(*data)->Value(kTestConfigTag));
}
template <typename T>
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index c59754db467..42067b6076b 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -1032,7 +1032,14 @@ class TestApiCallbacks {
template <typename T>
static TestApiCallbacks* FromInfo(const T& info) {
- void* data = v8::External::Cast(*info.Data())->Value(kTestApiCallbacksTag);
+ v8::Local<v8::Data> callback_data;
+ if constexpr (requires { info.DataV2(); }) {
+ callback_data = info.DataV2();
+ } else {
+ callback_data = info.Data();
+ }
+ void* data =
+ v8::External::Cast(*callback_data)->Value(kTestApiCallbacksTag);
return reinterpret_cast<TestApiCallbacks*>(data);
}
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index bdc2f12d7f4..aa7bbef607a 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -4275,7 +4275,7 @@ class ArchiveRestoreThread : public v8::internal::SandboxableThread,
v8::Local<v8::Context> context = v8::Context::New(isolate_);
v8::Context::Scope context_scope(context);
auto callback = [](const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Local<v8::Value> value = info.Data();
+ v8::Local<v8::Value> value = info.DataV2().As<v8::Value>();
CHECK(value->IsExternal());
auto art = static_cast<ArchiveRestoreThread*>(
v8::Local<v8::External>::Cast(value)->Value(
@@ -6364,7 +6364,7 @@ void RejectPromiseThroughCppInternal(
const v8::FunctionCallbackInfo<v8::Value>& info, bool silent) {
CHECK(i::ValidateCallbackInfo(info));
auto data = reinterpret_cast<std::pair<v8::Isolate*, LocalContext*>*>(
- info.Data().As<v8::External>()->Value(kDataTag));
+ info.DataV2().As<v8::External>()->Value(kDataTag));
v8::Local<v8::String> value1 =
v8::String::NewFromUtf8Literal(data->first, "foo");
@@ -6766,9 +6766,7 @@ class ScopeListener : public v8::debug::DebugDelegate {
auto frame_inspector =
std::make_unique<i::FrameInspector>(iterator_.frame(), 0, isolate);
- i::ScopeIterator scope_iterator(
- isolate, frame_inspector.get(),
- i::ScopeIterator::ReparseStrategy::kScriptIfNeeded);
+ i::ScopeIterator scope_iterator(isolate, frame_inspector.get());
// Iterate all scopes triggering block list creation along the way. This
// should not run into any CHECKs.
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index 902973afc62..81895814bfb 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -4351,6 +4351,85 @@ TEST(SamplingHeapProfilerApiSamples) {
heap_profiler->StopSamplingHeapProfiler();
}
+TEST(SamplingHeapProfilerSetInterval) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
+
+ i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
+
+ const uint64_t initial_interval = 1024;
+ const uint64_t updated_interval = 4096;
+ heap_profiler->StartSamplingHeapProfiler(initial_interval);
+
+ CompileRun("for (var i = 0; i < 1024; i++) new Array(64);");
+ auto samples_before = heap_profiler->GetSamplingHeapProfilerSamples();
+ CHECK_GT(samples_before.size(), 0u);
+ uint64_t max_id_before = 0;
+ for (const auto& s : samples_before) {
+ CHECK_EQ(initial_interval, s.sample_interval);
+ if (s.sample_id > max_id_before) max_id_before = s.sample_id;
+ }
+
+ heap_profiler->SetSamplingHeapProfilerInterval(updated_interval);
+ CompileRun("for (var i = 0; i < 1024; i++) new Array(64);");
+
+ bool saw_new_sample = false;
+ for (const auto& s : heap_profiler->GetSamplingHeapProfilerSamples()) {
+ if (s.sample_id > max_id_before) {
+ CHECK_EQ(updated_interval, s.sample_interval);
+ saw_new_sample = true;
+ } else {
+ CHECK_EQ(initial_interval, s.sample_interval);
+ }
+ }
+ CHECK(saw_new_sample);
+
+ heap_profiler->StopSamplingHeapProfiler();
+}
+
+TEST(SamplingHeapProfilerSampleIntervalSurvivesGC) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
+
+ i::v8_flags.sampling_heap_profiler_suppress_randomness = true;
+
+ const uint64_t interval = 1024;
+ heap_profiler->StartSamplingHeapProfiler(
+ interval, 16,
+ static_cast<v8::HeapProfiler::SamplingFlags>(
+ v8::HeapProfiler::kSamplingIncludeObjectsCollectedByMajorGC));
+
+ CompileRun("for (var i = 0; i < 1024; i++) new Array(64);");
+ i::heap::InvokeMajorGC(CcTest::heap());
+
+ bool saw_dead = false;
+ for (const auto& s : heap_profiler->GetSamplingHeapProfilerSamples()) {
+ CHECK_EQ(interval, s.sample_interval);
+ if (!s.is_live) saw_dead = true;
+ }
+ CHECK(saw_dead);
+
+ heap_profiler->StopSamplingHeapProfiler();
+}
+
+TEST(SamplingHeapProfilerSetIntervalNoop) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::HeapProfiler* heap_profiler = env.isolate()->GetHeapProfiler();
+
+ // Safe before Start.
+ heap_profiler->SetSamplingHeapProfilerInterval(2048);
+ CHECK_EQ(0u, heap_profiler->GetSamplingHeapProfilerSamples().size());
+
+ // Safe after Stop.
+ heap_profiler->StartSamplingHeapProfiler(1024);
+ heap_profiler->StopSamplingHeapProfiler();
+ heap_profiler->SetSamplingHeapProfilerInterval(2048);
+ CHECK_EQ(0u, heap_profiler->GetSamplingHeapProfilerSamples().size());
+}
+
TEST(SamplingHeapProfilerLeftTrimming) {
v8::HandleScope scope(CcTest::isolate());
LocalContext env;
diff --git a/deps/v8/test/cctest/test-js-weak-refs.cc b/deps/v8/test/cctest/test-js-weak-refs.cc
index 0c3d36e21f4..f1828d76727 100644
--- a/deps/v8/test/cctest/test-js-weak-refs.cc
+++ b/deps/v8/test/cctest/test-js-weak-refs.cc
@@ -123,19 +123,17 @@ class FakeAtomicPauseScope {
tracer_->StopAtomicPause();
tracer_->StopObservablePause(GarbageCollector::MARK_COMPACTOR,
base::TimeTicks::Now());
- if (heap_->cpp_heap()) {
- auto* cpp_heap = CppHeap::From(heap_->cpp_heap());
- cpp_heap->object_allocator().ResetLinearAllocationBuffers();
- cppgc::internal::StatsCollector* stats_collector =
- cpp_heap->stats_collector();
- stats_collector->NotifyMarkingStarted(
- cppgc::internal::CollectionType::kMajor,
- cppgc::Heap::MarkingType::kAtomic,
- cppgc::internal::MarkingConfig::IsForcedGC::kNotForced);
- stats_collector->NotifyMarkingCompleted(0);
- stats_collector->NotifySweepingCompleted(
- cppgc::Heap::SweepingType::kAtomic);
- }
+ auto* cpp_heap = CppHeap::From(heap_->cpp_heap());
+ cpp_heap->object_allocator().ResetLinearAllocationBuffers();
+ cppgc::internal::StatsCollector* stats_collector =
+ cpp_heap->stats_collector();
+ stats_collector->NotifyMarkingStarted(
+ cppgc::internal::CollectionType::kMajor,
+ cppgc::Heap::MarkingType::kAtomic,
+ cppgc::internal::MarkingConfig::IsForcedGC::kNotForced);
+ stats_collector->NotifyMarkingCompleted(0);
+ stats_collector->NotifySweepingCompleted(
+ cppgc::Heap::SweepingType::kAtomic);
tracer_->NotifyFullSweepingCompletedAndStopCycleIfFinished();
}
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 0bb7c47ad43..b60564dd309 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -74,6 +74,7 @@
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
#include "test/cctest/setup-isolate-for-tests.h"
+#include "test/common/version-utils.h"
namespace v8 {
namespace internal {
@@ -209,15 +210,13 @@ StartupBlobs Serialize(v8::Isolate* isolate) {
i_isolate->read_only_heap()->OnCreateHeapObjectsComplete(i_isolate);
}
- ReadOnlySerializer read_only_serializer(i_isolate,
- Snapshot::kDefaultSerializerFlags);
+ Snapshot::SerializerFlags flags(Snapshot::kAllowSerializingAllTrustedObjects);
+ ReadOnlySerializer read_only_serializer(i_isolate, flags);
read_only_serializer.Serialize();
- SharedHeapSerializer shared_space_serializer(
- i_isolate, Snapshot::kDefaultSerializerFlags);
+ SharedHeapSerializer shared_space_serializer(i_isolate, flags);
- StartupSerializer ser(i_isolate, Snapshot::kDefaultSerializerFlags,
- &shared_space_serializer);
+ StartupSerializer ser(i_isolate, flags, &shared_space_serializer);
ser.SerializeStrongReferences(no_gc);
ser.SerializeWeakReferencesAndDeferred();
@@ -428,22 +427,22 @@ static void SerializeContext(base::Vector<const uint8_t>* startup_blob_out,
isolate->read_only_heap()->OnCreateHeapObjectsComplete(isolate);
}
+ Snapshot::SerializerFlags flags(
+ Snapshot::kAllowSerializingAllTrustedObjects);
SnapshotByteSink read_only_sink;
- ReadOnlySerializer read_only_serializer(isolate,
- Snapshot::kDefaultSerializerFlags);
+ ReadOnlySerializer read_only_serializer(isolate, flags);
read_only_serializer.Serialize();
- SharedHeapSerializer shared_space_serializer(
- isolate, Snapshot::kDefaultSerializerFlags);
+ SharedHeapSerializer shared_space_serializer(isolate, flags);
SnapshotByteSink startup_sink;
- StartupSerializer startup_serializer(
- isolate, Snapshot::kDefaultSerializerFlags, &shared_space_serializer);
+ StartupSerializer startup_serializer(isolate, flags,
+ &shared_space_serializer);
startup_serializer.SerializeStrongReferences(no_gc);
SnapshotByteSink context_sink;
ContextSerializer context_serializer(
- isolate, Snapshot::kDefaultSerializerFlags, &startup_serializer,
+ isolate, flags, &startup_serializer,
SerializeEmbedderFieldsCallback(v8::SerializeInternalFieldsCallback()));
context_serializer.Serialize(&raw_context, no_gc);
@@ -622,23 +621,22 @@ static void SerializeCustomContext(
i_isolate->read_only_heap()->OnCreateHeapObjectsComplete(i_isolate);
}
+ Snapshot::SerializerFlags flags(
+ Snapshot::kAllowSerializingAllTrustedObjects);
SnapshotByteSink read_only_sink;
- ReadOnlySerializer read_only_serializer(
- i_isolate, Snapshot::kDefaultSerializerFlags);
+ ReadOnlySerializer read_only_serializer(i_isolate, flags);
read_only_serializer.Serialize();
- SharedHeapSerializer shared_space_serializer(
- i_isolate, Snapshot::kDefaultSerializerFlags);
+ SharedHeapSerializer shared_space_serializer(i_isolate, flags);
SnapshotByteSink startup_sink;
- StartupSerializer startup_serializer(i_isolate,
- Snapshot::kDefaultSerializerFlags,
+ StartupSerializer startup_serializer(i_isolate, flags,
&shared_space_serializer);
startup_serializer.SerializeStrongReferences(no_gc);
SnapshotByteSink context_sink;
ContextSerializer context_serializer(
- i_isolate, Snapshot::kDefaultSerializerFlags, &startup_serializer,
+ i_isolate, flags, &startup_serializer,
SerializeEmbedderFieldsCallback(
v8::SerializeInternalFieldsCallback()));
context_serializer.Serialize(&raw_context, no_gc);
@@ -3110,15 +3108,12 @@ static void SerializerLogEventListener(const v8::JitCodeEvent* event) {
}
v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
- const char* js_source, CodeCacheType cacheType = CodeCacheType::kLazy) {
+ v8::Isolate* isolate, const char* js_source, CodeCacheType cacheType) {
v8::ScriptCompiler::CachedData* cache;
- v8::Isolate::CreateParams create_params;
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- v8::Isolate* isolate1 = v8::Isolate::New(create_params);
{
- v8::Isolate::Scope iscope(isolate1);
- v8::HandleScope scope(isolate1);
- v8::Local<v8::Context> context = v8::Context::New(isolate1);
+ v8::Isolate::Scope iscope(isolate);
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::String> source_str = v8_str(js_source);
@@ -3137,7 +3132,7 @@ v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
UNREACHABLE();
}
v8::Local<v8::UnboundScript> script =
- v8::ScriptCompiler::CompileUnboundScript(isolate1, &source, options)
+ v8::ScriptCompiler::CompileUnboundScript(isolate, &source, options)
.ToLocalChecked();
if (cacheType != CodeCacheType::kAfterExecute) {
@@ -3145,11 +3140,11 @@ v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
}
v8::Local<v8::Value> result = script->BindToCurrentContext()
- ->Run(isolate1->GetCurrentContext())
+ ->Run(isolate->GetCurrentContext())
.ToLocalChecked();
v8::Local<v8::String> result_string =
- result->ToString(isolate1->GetCurrentContext()).ToLocalChecked();
- CHECK(result_string->Equals(isolate1->GetCurrentContext(), v8_str("abcdef"))
+ result->ToString(isolate->GetCurrentContext()).ToLocalChecked();
+ CHECK(result_string->Equals(isolate->GetCurrentContext(), v8_str("abcdef"))
.FromJust());
if (cacheType == CodeCacheType::kAfterExecute) {
@@ -3157,6 +3152,16 @@ v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
}
CHECK(cache);
}
+ return cache;
+}
+
+v8::ScriptCompiler::CachedData* CompileRunAndProduceCache(
+ const char* js_source, CodeCacheType cacheType = CodeCacheType::kLazy) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate1 = v8::Isolate::New(create_params);
+ v8::ScriptCompiler::CachedData* cache =
+ CompileRunAndProduceCache(isolate1, js_source, cacheType);
isolate1->Dispose();
return cache;
}
@@ -3457,6 +3462,42 @@ TEST(CachedDataCompatibilityCheck) {
}
}
+TEST(CodeSerializerEmbedderString) {
+ const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
+ std::unique_ptr<v8::ScriptCompiler::CachedData> empty_embedder_cache;
+ std::unique_ptr<v8::ScriptCompiler::CachedData> custom_embedder_cache;
+
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+
+ {
+ ScopedVersionEmbedderString embedder("");
+ empty_embedder_cache.reset(
+ CompileRunAndProduceCache(isolate, js_source, CodeCacheType::kLazy));
+ CHECK_EQ(empty_embedder_cache->CompatibilityCheck(isolate),
+ v8::ScriptCompiler::CachedData::kSuccess);
+ }
+
+ {
+ ScopedVersionEmbedderString embedder("-test");
+ CHECK_EQ(empty_embedder_cache->CompatibilityCheck(isolate),
+ v8::ScriptCompiler::CachedData::kVersionMismatch);
+ custom_embedder_cache.reset(
+ CompileRunAndProduceCache(isolate, js_source, CodeCacheType::kLazy));
+ CHECK_EQ(custom_embedder_cache->CompatibilityCheck(isolate),
+ v8::ScriptCompiler::CachedData::kSuccess);
+ }
+
+ {
+ ScopedVersionEmbedderString embedder("-test.2");
+ CHECK_EQ(custom_embedder_cache->CompatibilityCheck(isolate),
+ v8::ScriptCompiler::CachedData::kVersionMismatch);
+ }
+
+ isolate->Dispose();
+}
+
TEST(CodeSerializerBitFlip) {
i::v8_flags.verify_snapshot_checksum = true;
const char* js_source = "function f() { return 'abc'; }; f() + 'def'";
@@ -3742,11 +3783,11 @@ int serialized_static_field = 314;
void SerializedCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
- if (info.Data()->IsExternal()) {
- CHECK_EQ(info.Data().As<v8::External>()->Value(kIntPointerTag),
+ if (info.DataV2()->IsValue() && info.DataV2().As<v8::Value>()->IsExternal()) {
+ CHECK_EQ(info.DataV2().As<v8::External>()->Value(kIntPointerTag),
static_cast<void*>(&serialized_static_field));
int* value = reinterpret_cast<int*>(
- info.Data().As<v8::External>()->Value(kIntPointerTag));
+ info.DataV2().As<v8::External>()->Value(kIntPointerTag));
(*value)++;
}
info.GetReturnValue().Set(v8_num(42));
@@ -4827,11 +4868,9 @@ UNINITIALIZED_TEST(SerializeApiWrapperData) {
object_template->NewInstance(context).ToLocalChecked();
wrappable1 = cppgc::MakeGarbageCollected<DummyWrappable>(
cpp_heap->GetAllocationHandle());
- v8::Object::Wrap<v8::CppHeapPointerTag::kTagForTesting>(isolate, obj1,
- wrappable1);
- CHECK_EQ(
- wrappable1,
- v8::Object::Unwrap<CppHeapPointerTag::kTagForTesting>(isolate, obj1));
+ v8::Object::Wrap<i::kTagForTesting>(isolate, obj1, wrappable1);
+ CHECK_EQ(wrappable1,
+ v8::Object::Unwrap<i::kTagForTesting>(isolate, obj1));
CHECK(context->Global()->Set(context, v8_str("obj1"), obj1).FromJust());
v8::Local<v8::Object> obj2 =
@@ -4839,11 +4878,9 @@ UNINITIALIZED_TEST(SerializeApiWrapperData) {
wrappable2 = cppgc::MakeGarbageCollected<DummyWrappable>(
cpp_heap->GetAllocationHandle());
wrappable2->is_special = true;
- v8::Object::Wrap<v8::CppHeapPointerTag::kTagForTesting>(isolate, obj2,
- wrappable2);
- CHECK_EQ(
- wrappable2,
- v8::Object::Unwrap<CppHeapPointerTag::kTagForTesting>(isolate, obj2));
+ v8::Object::Wrap<i::kTagForTesting>(isolate, obj2, wrappable2);
+ CHECK_EQ(wrappable2,
+ v8::Object::Unwrap<i::kTagForTesting>(isolate, obj2));
CHECK(context->Global()->Set(context, v8_str("obj2"), obj2).FromJust());
creator.SetDefaultContext(context, SerializeInternalFieldsCallback(),
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 71378b07e02..7524353a07c 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -2274,7 +2274,7 @@ TEST(CheckIntlSegmentIteratorTerminateExecutionInterrupt) {
}
static void NotifyCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- auto self = Unwrap(args.Data());
+ auto self = Unwrap(args.DataV2().As<Value>());
{
v8::base::MutexGuard guard(self->m_);
self->did_enter_loop_ = true;
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-atomics64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-atomics64.cc
index 5e1bd186310..ffc567d7500 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-atomics64.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-atomics64.cc
@@ -181,7 +181,7 @@ WASM_EXEC_TEST(I64AtomicCompareExchange16U) {
}
}
-WASM_EXEC_TEST(I32AtomicCompareExchange8U) {
+WASM_EXEC_TEST(I64AtomicCompareExchange8U) {
WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
r.builder().SetMemoryShared();
@@ -199,6 +199,34 @@ WASM_EXEC_TEST(I32AtomicCompareExchange8U) {
}
}
+#define WASM_TEST_CAS_PRESERVES_EXPECTED(Name, CType, Representation) \
+ WASM_EXEC_TEST(I64AtomicCompareExchange##Name##PreservesExpected) { \
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier); \
+ CType* memory = \
+ r.builder().AddMemoryElems<CType>(kWasmPageSize / sizeof(CType)); \
+ r.builder().SetMemoryShared(); \
+ r.Build({WASM_ATOMICS_TERNARY_OP(kExprI64AtomicCompareExchange##Name, \
+ WASM_I32V_1(0), WASM_LOCAL_GET(0), \
+ WASM_LOCAL_GET(1), Representation), \
+ WASM_DROP, WASM_LOCAL_GET(0)}); \
+ FOR_UINT64_INPUTS(i) { \
+ CType initial = static_cast<CType>(i); \
+ FOR_UINT64_INPUTS(j) { \
+ CType replacement = static_cast<CType>(j); \
+ r.builder().WriteMemory(&memory[0], initial); \
+ CHECK_EQ(i, r.Call(i, j)); \
+ CType expected = \
+ CompareExchange(initial, static_cast<CType>(i), replacement); \
+ CHECK_EQ(expected, r.builder().ReadMemory(&memory[0])); \
+ } \
+ } \
+ }
+
+WASM_TEST_CAS_PRESERVES_EXPECTED(8U, uint8_t, MachineRepresentation::kWord8)
+WASM_TEST_CAS_PRESERVES_EXPECTED(16U, uint16_t, MachineRepresentation::kWord16)
+WASM_TEST_CAS_PRESERVES_EXPECTED(32U, uint32_t, MachineRepresentation::kWord32)
+#undef WASM_TEST_CAS_PRESERVES_EXPECTED
+
WASM_EXEC_TEST(I64AtomicLoad) {
WasmRunner<uint64_t> r(execution_tier);
uint64_t* memory =
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-wrappers.cc b/deps/v8/test/cctest/wasm/test-run-wasm-wrappers.cc
index 17751e788c8..730c17717c0 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-wrappers.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-wrappers.cc
@@ -196,8 +196,7 @@ TEST(WrapperReplacement) {
DirectHandle<Code> wrapper_before_call;
for (int i = remaining_budget; i > 0; --i) {
// Verify that the wrapper to be used is the generic one.
- wrapper_before_call =
- direct_handle(main_function_data->wrapper_code(isolate), isolate);
+ wrapper_before_call = direct_handle(main_export->code(isolate), isolate);
CHECK(IsGeneric(*wrapper_before_call));
// Call the function.
DirectHandle<Object> params[] = {SmiHandle(isolate, i)};
@@ -208,7 +207,7 @@ TEST(WrapperReplacement) {
}
// Get the wrapper-code object after the wrapper replacement.
- Tagged<Code> wrapper_after_call = main_function_data->wrapper_code(isolate);
+ Tagged<Code> wrapper_after_call = main_export->code(isolate);
// Verify that the budget has been exhausted.
CHECK_EQ(Smi::ToInt(main_function_data->wrapper_budget()->value()), 0);
@@ -286,9 +285,9 @@ TEST(EagerWrapperReplacement) {
kGenericWrapperBudget);
// Verify that all functions are set to use the generic wrapper.
- CHECK(IsGeneric(add_function_data->wrapper_code(isolate)));
- CHECK(IsGeneric(mult_function_data->wrapper_code(isolate)));
- CHECK(IsGeneric(id_function_data->wrapper_code(isolate)));
+ CHECK(IsGeneric(add_export->code(isolate)));
+ CHECK(IsGeneric(mult_export->code(isolate)));
+ CHECK(IsGeneric(id_export->code(isolate)));
// Call the add function to trigger the tier up.
{
@@ -303,9 +302,9 @@ TEST(EagerWrapperReplacement) {
kGenericWrapperBudget);
// Verify that the tier-up of the add function replaced the wrapper
// for both the add and the mult functions, but not the id function.
- CHECK(IsSpecific(add_function_data->wrapper_code(isolate)));
- CHECK(IsSpecific(mult_function_data->wrapper_code(isolate)));
- CHECK(IsGeneric(id_function_data->wrapper_code(isolate)));
+ CHECK(IsSpecific(add_export->code(isolate)));
+ CHECK(IsSpecific(mult_export->code(isolate)));
+ CHECK(IsGeneric(id_export->code(isolate)));
}
// Call the mult function to verify that the compiled wrapper is used.
@@ -384,7 +383,7 @@ TEST(WrapperReplacement_IndirectExport) {
// Verify that the generic-wrapper budget has initially a value of
// kGenericWrapperBudget and the wrapper to be used for calls to the
// indirect function is the generic one.
- CHECK(IsGeneric(indirect_function_data->wrapper_code(isolate)));
+ CHECK(IsGeneric(indirect_function->code(isolate)));
CHECK(Smi::ToInt(indirect_function_data->wrapper_budget()->value()) ==
kGenericWrapperBudget);
@@ -399,7 +398,7 @@ TEST(WrapperReplacement_IndirectExport) {
// Verify that the budget is now exhausted and the generic wrapper has been
// replaced by a specific one.
CHECK_EQ(Smi::ToInt(indirect_function_data->wrapper_budget()->value()), 0);
- CHECK(IsSpecific(indirect_function_data->wrapper_code(isolate)));
+ CHECK(IsSpecific(indirect_function->code(isolate)));
}
Cleanup();
}
diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
index 05bf5ccbade..f7f19c5aee4 100644
--- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
+++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
@@ -1280,8 +1280,8 @@ STREAM_TEST(TestIncrementalCaching) {
{
DirectHandle<Script> script = GetWasmEngine()->GetOrCreateScript(
i_isolate, tester.native_module().as_shared_ptr(), kNoSourceUrl);
- DirectHandle<WasmModuleObject> module_object = WasmModuleObject::New(
- i_isolate, tester.native_module().as_shared_ptr(), script);
+ DirectHandle<WasmModuleObject> module_object =
+ WasmModuleObject::New(i_isolate, script);
ErrorThrower thrower(i_isolate, "Instantiation");
// We instantiated before, so the second instantiation must also succeed:
instance = indirect_handle(
@@ -1880,6 +1880,53 @@ STREAM_TEST(Regress1334651) {
tester.RunCompilerTasks();
}
+STREAM_TEST(StreamingErrorCrashKeyReused) {
+ static int alloc_count = 0;
+ static int dummy_key = 0;
+ int set_count = 0;
+ std::string last_value;
+
+ isolate->SetCrashKeyStringCallbacks(
+ [](const char key[], v8::CrashKeySize size) -> v8::CrashKey {
+ CHECK_EQ(0, strcmp(key, "v8-wasm-streaming-error"));
+ CHECK_EQ(v8::CrashKeySize::Size1024, size);
+ ++alloc_count;
+ return &dummy_key;
+ },
+ [&](v8::CrashKey key, const std::string_view value) {
+ CHECK_EQ(&dummy_key, key);
+ ++set_count;
+ last_value = std::string(value);
+ });
+
+ {
+ StreamTester tester(isolate);
+ const uint8_t truncated_header[] = {0x00, 0x01, 0x02, 0x03};
+ tester.OnBytesReceived(truncated_header, arraysize(truncated_header));
+ tester.FinishStream();
+ tester.RunCompilerTasks();
+ CHECK(tester.IsPromiseRejected());
+ CHECK_EQ(1, alloc_count);
+ CHECK_EQ(1, set_count);
+ CHECK_EQ("StreamingDecoder failed", last_value);
+ }
+
+ {
+ StreamTester tester(isolate);
+ const uint8_t invalid_header[] = {0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07};
+ tester.OnBytesReceived(invalid_header, arraysize(invalid_header));
+ tester.FinishStream();
+ tester.RunCompilerTasks();
+ CHECK(tester.IsPromiseRejected());
+ CHECK_EQ(1, alloc_count);
+ CHECK_EQ(2, set_count);
+ CHECK(last_value.starts_with("ModuleDecoder: "));
+ }
+
+ isolate->SetCrashKeyStringCallbacks(nullptr, nullptr);
+}
+
#undef STREAM_TEST
} // namespace v8::internal::wasm
diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
index eb365875823..586563809bd 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
@@ -22,6 +22,7 @@
#include "src/wasm/wasm-serialization.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
+#include "test/common/version-utils.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/test-signatures.h"
#include "test/common/wasm/wasm-macro-gen.h"
@@ -32,9 +33,11 @@ namespace v8::internal::wasm {
// Approximate gtest TEST_F style, in case we adopt gtest.
class WasmSerializationTest {
public:
- WasmSerializationTest() : zone_(&allocator_, ZONE_NAME) {
+ explicit WasmSerializationTest(
+ const char* embedder_string = Version::GetEmbedder())
+ : zone_(&allocator_, ZONE_NAME) {
// Don't call here if we move to gtest.
- SetUp();
+ SetUp(embedder_string);
}
static constexpr const char* kFunctionName = "increment";
@@ -121,7 +124,7 @@ class WasmSerializationTest {
private:
Zone* zone() { return &zone_; }
- void SetUp() {
+ void SetUp(const char* embedder_string) {
CcTest::InitIsolateOnce();
ZoneBuffer buffer(&zone_);
WasmSerializationTest::BuildWireBytes(zone(), &buffer);
@@ -180,6 +183,7 @@ class WasmSerializationTest {
while (data_.size == 0) {
testing::CallWasmFunctionForTesting(serialization_isolate, instance,
kFunctionName, {});
+ ScopedVersionEmbedderString embedder(embedder_string);
data_ = compiled_module.Serialize();
}
CHECK_LT(0, data_.size);
@@ -246,6 +250,32 @@ TEST(DeserializeMismatchingVersion) {
test.CollectGarbage();
}
+TEST(DeserializeEmbedderString) {
+ {
+ WasmSerializationTest test("");
+ {
+ HandleScope scope(CcTest::i_isolate());
+ ScopedVersionEmbedderString embedder("");
+ CHECK(!test.Deserialize().is_null());
+ ScopedVersionEmbedderString mismatching_embedder("-test");
+ CHECK(test.Deserialize().is_null());
+ }
+ test.CollectGarbage();
+ }
+
+ {
+ WasmSerializationTest test("-test");
+ {
+ HandleScope scope(CcTest::i_isolate());
+ ScopedVersionEmbedderString embedder("-test");
+ CHECK(!test.Deserialize().is_null());
+ ScopedVersionEmbedderString mismatching_embedder("-test.2");
+ CHECK(test.Deserialize().is_null());
+ }
+ test.CollectGarbage();
+ }
+}
+
TEST(DeserializeNoSerializedData) {
WasmSerializationTest test;
{
diff --git a/deps/v8/test/common/version-utils.h b/deps/v8/test/common/version-utils.h
new file mode 100644
index 00000000000..937877c617a
--- /dev/null
+++ b/deps/v8/test/common/version-utils.h
@@ -0,0 +1,31 @@
+// Copyright 2026 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 V8_TEST_COMMON_VERSION_UTILS_H_
+#define V8_TEST_COMMON_VERSION_UTILS_H_
+
+#include "src/utils/version.h"
+
+namespace v8::internal {
+
+class ScopedVersionEmbedderString final {
+ public:
+ explicit ScopedVersionEmbedderString(const char* embedder)
+ : previous_(Version::embedder_) {
+ Version::embedder_ = embedder;
+ }
+
+ ~ScopedVersionEmbedderString() { Version::embedder_ = previous_; }
+
+ ScopedVersionEmbedderString(const ScopedVersionEmbedderString&) = delete;
+ ScopedVersionEmbedderString& operator=(const ScopedVersionEmbedderString&) =
+ delete;
+
+ private:
+ const char* const previous_;
+};
+
+} // namespace v8::internal
+
+#endif // V8_TEST_COMMON_VERSION_UTILS_H_
diff --git a/deps/v8/test/common/wasm/fuzzer-common.cc b/deps/v8/test/common/wasm/fuzzer-common.cc
index 5ea6707ef64..4f3ba70d0ca 100644
--- a/deps/v8/test/common/wasm/fuzzer-common.cc
+++ b/deps/v8/test/common/wasm/fuzzer-common.cc
@@ -477,7 +477,7 @@ MaybeDirectHandle<WasmModuleObject> CompileReferenceModule(
TypeCanonicalizer::PrepareForCanonicalTypeId(
isolate, module->MaxCanonicalTypeIndex(),
SharedFlag{module->has_shared_part});
- return WasmModuleObject::New(isolate, std::move(native_module), script);
+ return WasmModuleObject::New(isolate, script);
}
#if V8_ENABLE_DRUMBRAKE
diff --git a/deps/v8/test/common/wasm/wasm-run-utils.cc b/deps/v8/test/common/wasm/wasm-run-utils.cc
index e7b753b7131..b3f98b70bca 100644
--- a/deps/v8/test/common/wasm/wasm-run-utils.cc
+++ b/deps/v8/test/common/wasm/wasm-run-utils.cc
@@ -482,7 +482,7 @@ DirectHandle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
isolate_->factory()->NewByteArray(kMaxGlobalsSize);
std::fill(globals_buffer->begin(), globals_buffer->end(), 0);
DirectHandle<WasmModuleObject> module_object =
- WasmModuleObject::New(isolate_, native_module, script);
+ WasmModuleObject::New(isolate_, script);
native_module_ = native_module.get();
DirectHandle<WasmTrustedInstanceData> trusted_data =
diff --git a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-reuse.js b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-reuse.js
index 371012a0db8..b7abd6ec81e 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-reuse.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-reuse.js
@@ -287,6 +287,68 @@ listener_delegate = function(exec_state) {
(test_outer_shadow())();
EndTest();
+BeginTest("Check evaluating on outer closure scopes when inner scope also has a context");
+function test_outer_shadow_with_inner_context() {
+ let x = 'outer_stack';
+ let closure_y = 'closure_y';
+ () => closure_y; // force context allocation for test_outer_shadow_with_inner_context
+ return function inner() {
+ let inner_ctx = 'inner_ctx';
+ () => inner_ctx; // force context allocation for inner as well
+ debugger;
+ };
+}
+listener_delegate = function(exec_state) {
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate("x").value(), ReferenceError);
+ assertEquals('closure_y', exec_state.frame(0).scope(1).evaluate("closure_y").value());
+};
+(test_outer_shadow_with_inner_context())();
+EndTest();
+
+BeginTest("Check that inner block locals do not leak into outer function block list");
+var a_block_test = 'global_a';
+var c_block_test = 'global_c';
+function test_inner_block_isolation() {
+ let a_block_test = 42; // stack-allocated in f
+ let b_block_test = 21;
+ () => b_block_test; // force context-allocation so f has a context
+ {
+ const c_block_test = 'foo'; // stack-allocated in inner block
+ (function g() {
+ if (break_position === 1) debugger;
+ })();
+ }
+ return function h() {
+ if (break_position === 2) debugger;
+ };
+}
+
+listener_delegate = function(exec_state) {
+ // In `g` (inside the inner block), both `a_block_test` and `c_block_test` are shadowed.
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("a_block_test").value(), ReferenceError);
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("c_block_test").value(), ReferenceError);
+ assertEquals(21, exec_state.frame(0).scope(0).evaluate("b_block_test").value());
+
+ // In `f` (`scope(1)`), `a_block_test` is shadowed, but `c_block_test` (from the inner block) is not.
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate("a_block_test").value(), ReferenceError);
+ assertEquals('global_c', exec_state.frame(0).scope(1).evaluate("c_block_test").value());
+ assertEquals(21, exec_state.frame(0).scope(1).evaluate("b_block_test").value());
+};
+break_position = 1;
+(test_inner_block_isolation())();
+EndTest();
+
+BeginTest("Check that inner block locals do not leak into sibling closure after reuse");
+listener_delegate = function(exec_state) {
+ // In `h` (outside the inner block), `a_block_test` is shadowed, but `c_block_test` is not.
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("a_block_test").value(), ReferenceError);
+ assertEquals('global_c', exec_state.frame(0).scope(0).evaluate("c_block_test").value());
+ assertEquals(21, exec_state.frame(0).scope(0).evaluate("b_block_test").value());
+};
+break_position = 2;
+(test_inner_block_isolation())();
+EndTest();
+
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,
diff --git a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js
index 8f4024f58d6..36578548f6f 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js
@@ -254,6 +254,68 @@ listener_delegate = function(exec_state) {
(test_outer_shadow())();
EndTest();
+BeginTest("Check evaluating on outer closure scopes when inner scope also has a context");
+function test_outer_shadow_with_inner_context() {
+ let x = 'outer_stack';
+ let closure_y = 'closure_y';
+ () => closure_y; // force context allocation for test_outer_shadow_with_inner_context
+ return function inner() {
+ let inner_ctx = 'inner_ctx';
+ () => inner_ctx; // force context allocation for inner as well
+ debugger;
+ };
+}
+listener_delegate = function(exec_state) {
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate("x").value(), ReferenceError);
+ assertEquals('closure_y', exec_state.frame(0).scope(1).evaluate("closure_y").value());
+};
+(test_outer_shadow_with_inner_context())();
+EndTest();
+
+BeginTest("Check that inner block locals do not leak into outer function block list");
+var a_block_test = 'global_a';
+var c_block_test = 'global_c';
+function test_inner_block_isolation() {
+ let a_block_test = 42; // stack-allocated in f
+ let b_block_test = 21;
+ () => b_block_test; // force context-allocation so f has a context
+ {
+ const c_block_test = 'foo'; // stack-allocated in inner block
+ (function g() {
+ if (break_position === 1) debugger;
+ })();
+ }
+ return function h() {
+ if (break_position === 2) debugger;
+ };
+}
+
+listener_delegate = function(exec_state) {
+ // In `g` (inside the inner block), both `a_block_test` and `c_block_test` are shadowed.
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("a_block_test").value(), ReferenceError);
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("c_block_test").value(), ReferenceError);
+ assertEquals(21, exec_state.frame(0).scope(0).evaluate("b_block_test").value());
+
+ // In `f` (`scope(1)`), `a_block_test` is shadowed, but `c_block_test` (from the inner block) is not.
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate("a_block_test").value(), ReferenceError);
+ assertEquals('global_c', exec_state.frame(0).scope(1).evaluate("c_block_test").value());
+ assertEquals(21, exec_state.frame(0).scope(1).evaluate("b_block_test").value());
+};
+break_position = 1;
+(test_inner_block_isolation())();
+EndTest();
+
+BeginTest("Check that inner block locals do not leak into sibling closure after reuse");
+listener_delegate = function(exec_state) {
+ // In `h` (outside the inner block), `a_block_test` is shadowed, but `c_block_test` is not.
+ assertThrows(() => exec_state.frame(0).scope(0).evaluate("a_block_test").value(), ReferenceError);
+ assertEquals('global_c', exec_state.frame(0).scope(0).evaluate("c_block_test").value());
+ assertEquals(21, exec_state.frame(0).scope(0).evaluate("b_block_test").value());
+};
+break_position = 2;
+(test_inner_block_isolation())();
+EndTest();
+
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,
diff --git a/deps/v8/test/fuzzer/multi-return.cc b/deps/v8/test/fuzzer/multi-return.cc
index 8ad028a8c73..d232ff2db2d 100644
--- a/deps/v8/test/fuzzer/multi-return.cc
+++ b/deps/v8/test/fuzzer/multi-return.cc
@@ -16,6 +16,7 @@
#include "src/compiler/turbofan-graph.h"
#include "src/compiler/wasm-compiler.h"
#include "src/execution/simulator.h"
+#include "src/wasm/function-compiler.h"
#include "src/wasm/wasm-code-pointer-table-inl.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-features.h"
@@ -246,18 +247,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
callee.Return(static_cast<int>(desc->ReturnCount()), returns.get());
OptimizedCompilationInfo info(base::ArrayVector("testing"), &zone,
- CodeKind::FOR_TESTING);
- DirectHandle<Code> code =
- Pipeline::GenerateCodeForTesting(&info, i_isolate, desc, callee.graph(),
- AssemblerOptions::Default(i_isolate),
- callee.ExportForTest())
- .ToHandleChecked();
+ CodeKind::WASM_FUNCTION);
+ wasm::WasmCompilationResult wasm_result =
+ Pipeline::GenerateWasmCodeForTesting(
+ &info, i_isolate, desc, callee.graph(),
+ AssemblerOptions::Default(i_isolate), callee.ExportForTest());
+ CHECK(wasm_result.succeeded());
std::shared_ptr<wasm::NativeModule> module =
- AllocateNativeModule(i_isolate, code->instruction_size());
+ AllocateNativeModule(i_isolate, wasm_result.code_desc.instr_size);
wasm::WasmCodeRefScope wasm_code_ref_scope;
wasm::WasmCode* wasm_code =
- module->AddCodeForTesting(code, desc->signature_hash());
+ module->AddCodeForTesting(wasm_result, desc->signature_hash());
WasmCodePointer code_pointer =
wasm::GetProcessWideWasmCodePointerTable()->AllocateAndInitializeEntry(
wasm_code->instruction_start(), wasm_code->signature_hash());
@@ -267,8 +268,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
MachineSignature::Builder sig_builder(&zone, 1, 0);
sig_builder.AddReturn(MachineType::Int32());
- CallDescriptor* wrapper_desc =
- Linkage::GetSimplifiedCDescriptor(&zone, sig_builder.Get());
+ // The wrapper is called from C++ and calls an off-heap WasmCode function.
+ // Initialize the root register so runtime calls or traps can access the
+ // isolate.
+ CallDescriptor* wrapper_desc = Linkage::GetSimplifiedCDescriptor(
+ &zone, sig_builder.Get(), CallDescriptor::kInitializeRootRegister);
RawMachineAssembler caller(
i_isolate, zone.New<TFGraph>(&zone), wrapper_desc,
MachineType::PointerRepresentation(),
diff --git a/deps/v8/test/fuzzer/wasm/deopt.cc b/deps/v8/test/fuzzer/wasm/deopt.cc
index 962cabd4895..104b5153157 100644
--- a/deps/v8/test/fuzzer/wasm/deopt.cc
+++ b/deps/v8/test/fuzzer/wasm/deopt.cc
@@ -275,6 +275,10 @@ int FuzzIt(base::Vector<const uint8_t> data) {
const bool optimize_main_function =
inlinees.empty() || data.empty() || !(data.last() & 1);
#if defined(DEBUG) && defined(V8_USE_ADDRESS_SANITIZER)
+ // Disable register allocator verification on slow builds (Debug + ASan) to
+ // avoid timeouts in TurboFan/Turboshaft compilation on pathological inputs
+ // (see crbug.com/527760872).
+ FlagScope<bool> no_verify_allocator(&v8_flags.turbo_verify_allocation, false);
// Disable type assertions on slow builds (Debug + ASan) to avoid timeouts in
// TurboFan compilation (see crbug.com/520317061).
const bool assert_types = false;
diff --git a/deps/v8/test/inspector/BUILD.gn b/deps/v8/test/inspector/BUILD.gn
index 6b56d9a2517..594ff77ca7f 100644
--- a/deps/v8/test/inspector/BUILD.gn
+++ b/deps/v8/test/inspector/BUILD.gn
@@ -23,6 +23,7 @@ v8_source_set("inspector_test") {
public_deps = [
"../..:v8",
+ "../..:v8_internal_headers",
"../..:v8_libbase",
"../..:v8_libplatform",
"../../src/inspector:inspector_test_headers",
diff --git a/deps/v8/test/inspector/console/stack-tagging-expected.txt b/deps/v8/test/inspector/console/stack-tagging-expected.txt
index c84cf3b658a..94771db245a 100644
--- a/deps/v8/test/inspector/console/stack-tagging-expected.txt
+++ b/deps/v8/test/inspector/console/stack-tagging-expected.txt
@@ -127,8 +127,8 @@ Expected exception:
Running test: runThrowsAnErrorWhenCalledWithNullReceiver
Expected exception:
{
- className : Error
- description : Error: 'run' called with illegal receiver. at runThrowsAnErrorWhenCalledWithNullReceiver (runThrowsAnErrorWhenCalledWithNullReceiver.js:3:14) at runThrowsAnErrorWhenCalledWithNullReceiver.js:4:5
+ className : TypeError
+ description : TypeError: Illegal invocation at runThrowsAnErrorWhenCalledWithNullReceiver (runThrowsAnErrorWhenCalledWithNullReceiver.js:3:14) at runThrowsAnErrorWhenCalledWithNullReceiver.js:4:5
objectId : <objectId>
subtype : error
type : object
@@ -137,8 +137,8 @@ Expected exception:
Running test: runThrowsAnErrorWhenCalledWithIllegalReceiver
Expected exception:
{
- className : Error
- description : Error: 'run' called with illegal receiver. at runThrowsAnErrorWhenCalledWithIllegalReceiver (runThrowsAnErrorWhenCalledWithIllegalReceiver.js:3:14) at runThrowsAnErrorWhenCalledWithIllegalReceiver.js:4:5
+ className : TypeError
+ description : TypeError: Illegal invocation at runThrowsAnErrorWhenCalledWithIllegalReceiver (runThrowsAnErrorWhenCalledWithIllegalReceiver.js:3:14) at runThrowsAnErrorWhenCalledWithIllegalReceiver.js:4:5
objectId : <objectId>
subtype : error
type : object
diff --git a/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt b/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt
index 39da6a89fdc..a5b131ed3c0 100644
--- a/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt
+++ b/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt
@@ -18,6 +18,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 3
lineNumber : 5
@@ -91,6 +92,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 13
lineNumber : 14
@@ -199,6 +201,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 13
lineNumber : 14
@@ -272,6 +275,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 2
lineNumber : 11
@@ -433,6 +437,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 13
lineNumber : 14
@@ -506,6 +511,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 2
lineNumber : 11
@@ -667,6 +673,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 13
lineNumber : 14
@@ -740,6 +747,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 2
lineNumber : 11
@@ -901,6 +909,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 3
lineNumber : 9
@@ -974,6 +983,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 13
lineNumber : 14
@@ -1047,6 +1057,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 2
lineNumber : 11
diff --git a/deps/v8/test/inspector/debugger/class-private-fields-scopes-expected.txt b/deps/v8/test/inspector/debugger/class-private-fields-scopes-expected.txt
index b302e1d4658..6dbacb6705b 100644
--- a/deps/v8/test/inspector/debugger/class-private-fields-scopes-expected.txt
+++ b/deps/v8/test/inspector/debugger/class-private-fields-scopes-expected.txt
@@ -18,6 +18,7 @@ Running test: testScopesPaused
}
scopeChain : [
[0] : {
+ empty : true
endLocation : {
columnNumber : 5
lineNumber : 6
diff --git a/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes-expected.txt b/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes-expected.txt
new file mode 100644
index 00000000000..06cf6e1aefc
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes-expected.txt
@@ -0,0 +1,13 @@
+Tests that functions created via the Function constructor do not expose a self-binding named "anonymous" to the debugger.
+
+Running test: setUp
+
+Running test: testDirect
+Paused in '':
+ [0] local: a
+ anonymous = string: global anonymous
+
+Running test: testNested
+Paused in 'inner':
+ [0] local:
+ anonymous = string: global anonymous
diff --git a/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes.js b/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes.js
new file mode 100644
index 00000000000..208a361caaf
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/function-constructor-anonymous-scopes.js
@@ -0,0 +1,50 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Tests that functions created via the Function constructor do not ' +
+ 'expose a self-binding named "anonymous" to the debugger.');
+
+contextGroup.addScript(`
+var anonymous = 'global anonymous';
+var direct = new Function('a', 'debugger; return anonymous;');
+var nested = new Function('a',
+ 'return function inner() { debugger; return anonymous; }');
+//# sourceURL=test.js`);
+
+async function pauseAndCheck(expression) {
+ const paused = Protocol.Debugger.oncePaused();
+ Protocol.Runtime.evaluate({expression});
+ const {params: {callFrames: [callFrame]}} = await paused;
+ InspectorTest.log(`Paused in '${callFrame.functionName}':`);
+ for (let i = 0; i < callFrame.scopeChain.length; ++i) {
+ const scope = callFrame.scopeChain[i];
+ if (scope.type === 'global') continue;
+ const {result: {result: variables}} = await Protocol.Runtime.getProperties(
+ {objectId: scope.object.objectId, ownProperties: true});
+ InspectorTest.log(
+ ` [${i}] ${scope.type}: ${variables.map(v => v.name).join(', ')}`);
+ }
+ const {result: {result}} = await Protocol.Debugger.evaluateOnCallFrame({
+ callFrameId: callFrame.callFrameId,
+ expression: 'typeof anonymous + ": " + String(anonymous).split("\\n")[0]'
+ });
+ InspectorTest.log(` anonymous = ${result.value}`);
+ await Protocol.Debugger.resume();
+}
+
+InspectorTest.runAsyncTestSuite([
+ async function setUp() {
+ await Protocol.Debugger.enable();
+ await Protocol.Runtime.enable();
+ },
+
+ async function testDirect() {
+ await pauseAndCheck('direct(1)');
+ },
+
+ async function testNested() {
+ await pauseAndCheck('nested(1)()');
+ },
+]);
diff --git a/deps/v8/test/inspector/runtime/regress-553931056-expected.txt b/deps/v8/test/inspector/runtime/regress-553931056-expected.txt
new file mode 100644
index 00000000000..c2f59a934c3
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-553931056-expected.txt
@@ -0,0 +1,92 @@
+Tests that custom preview formatters prevent TOCTOU and sanitization bypasses
+1. Test microtask TOCTOU attack on body() and verify no objectId leak to page JS..
+customPreview: ["span",{},"Header ok"]
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : object
+ value : [
+ [0] : div
+ [1] : {
+ }
+ [2] : [
+ [0] : object
+ [1] : {
+ className : Object
+ customPreview : {
+ bodyGetterId : <bodyGetterId>
+ header : ["span",{},"Header ok"]
+ }
+ description : Object
+ objectId : <objectId>
+ type : object
+ }
+ ]
+ [3] : [
+ [0] : span
+ [1] : {
+ }
+ [2] : benign
+ ]
+ ]
+ }
+ }
+}
+microtaskObservedObjectId in page JS: undefined
+2. Test toJSON() bypass attempt in header() and body()..
+customPreview: ["span",{},["span",{},"initial"]]
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : object
+ value : [
+ [0] : div
+ [1] : {
+ }
+ [2] : [
+ [0] : span
+ [1] : {
+ }
+ [2] : initial
+ ]
+ ]
+ }
+ }
+}
+toJSONCalled: false
+3. Test getter mutating earlier validated element during traversal..
+customPreview: ["div",{},["span",{},"safe-child"],"trigger"]
+4. Test new String("object") unboxing bypass attempt..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught tag name must be a string
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
+5. Test ["object", forged, "extra"] (length != 2) bypass attempt..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught object tag should have 2 elements
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
diff --git a/deps/v8/test/inspector/runtime/regress-553931056.js b/deps/v8/test/inspector/runtime/regress-553931056.js
new file mode 100644
index 00000000000..78d75d26d64
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-553931056.js
@@ -0,0 +1,143 @@
+// Copyright 2026 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.
+//
+// Regression test for b/553931056.
+
+const { session, contextGroup, Protocol } =
+ InspectorTest.start('Tests that custom preview formatters prevent TOCTOU and sanitization bypasses');
+
+(async function test() {
+ Protocol.Runtime.enable();
+ Protocol.Runtime.setCustomObjectFormatterEnabled({ enabled: true });
+ Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
+
+ InspectorTest.log('1. Test microtask TOCTOU attack on body() and verify no objectId leak to page JS..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ var microtaskObservedObjectId = 'not-run';
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, 'Header ok'],
+ hasBody: () => true,
+ body: () => {
+ const trustedSlot = ['object', { object: { real: 1 } }];
+ const victimSlot = ['span', {}, 'benign'];
+ const tree = ['div', {}, trustedSlot, victimSlot];
+ Promise.resolve().then(() => {
+ microtaskObservedObjectId = trustedSlot[1].objectId;
+ victimSlot.length = 0;
+ victimSlot.push('object', {
+ type: 'object',
+ objectId: 'forged-id',
+ description: 'forged-remote-object'
+ });
+ });
+ return tree;
+ }
+ }];
+ `
+ });
+ let evalRes = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ await dumpCustomPreviewWithBody(evalRes);
+ let leakRes = await Protocol.Runtime.evaluate({ expression: 'String(microtaskObservedObjectId)' });
+ InspectorTest.log('microtaskObservedObjectId in page JS: ' + leakRes.result.result.value);
+
+ InspectorTest.log('2. Test toJSON() bypass attempt in header() and body()..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ var toJSONCalled = false;
+ const sneakyChild = ['span', {}, 'initial'];
+ sneakyChild.toJSON = () => {
+ toJSONCalled = true;
+ return ['object', { type: 'object', objectId: 'forged-via-toJSON' }];
+ };
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, sneakyChild],
+ hasBody: () => true,
+ body: () => ['div', {}, sneakyChild]
+ }];
+ `
+ });
+ evalRes = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ await dumpCustomPreviewWithBody(evalRes);
+ let toJSONRes = await Protocol.Runtime.evaluate({ expression: 'toJSONCalled' });
+ InspectorTest.log('toJSONCalled: ' + toJSONRes.result.result.value);
+
+ InspectorTest.log('3. Test getter mutating earlier validated element during traversal..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => {
+ const firstChild = ['span', {}, 'safe-child'];
+ const tree = ['div', {}, firstChild];
+ Object.defineProperty(tree, '3', {
+ enumerable: true,
+ get() {
+ firstChild[0] = 'object';
+ firstChild[1] = { type: 'object', objectId: 'forged-via-getter' };
+ firstChild.length = 2;
+ return 'trigger';
+ }
+ });
+ return tree;
+ },
+ hasBody: () => false
+ }];
+ `
+ });
+ evalRes = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(evalRes);
+
+ InspectorTest.log('4. Test new String("object") unboxing bypass attempt..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, [new String('object'), { type: 'object', objectId: 'forged-string-obj' }]],
+ hasBody: () => false
+ }];
+ `
+ });
+ evalRes = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(evalRes);
+
+ InspectorTest.log('5. Test ["object", forged, "extra"] (length != 2) bypass attempt..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, ['object', { type: 'object', objectId: 'forged-len-3' }, 'extra']],
+ hasBody: () => false
+ }];
+ `
+ });
+ evalRes = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(evalRes);
+
+ InspectorTest.completeTest();
+})();
+
+function dumpCustomPreview(result) {
+ const remoteObject = result.result.result;
+ if (remoteObject.customPreview) {
+ InspectorTest.log('customPreview: ' + remoteObject.customPreview.header);
+ } else {
+ InspectorTest.log('No customPreview generated');
+ }
+}
+
+async function dumpCustomPreviewWithBody(result) {
+ const remoteObject = result.result.result;
+ if (remoteObject.customPreview) {
+ InspectorTest.log('customPreview: ' + remoteObject.customPreview.header);
+ if (remoteObject.customPreview.bodyGetterId) {
+ const body = await Protocol.Runtime.callFunctionOn({
+ objectId: remoteObject.objectId,
+ functionDeclaration: 'function(bodyGetter) { return bodyGetter.call(this); }',
+ arguments: [{ objectId: remoteObject.customPreview.bodyGetterId }],
+ returnByValue: true
+ });
+ InspectorTest.logMessage(body);
+ }
+ } else {
+ InspectorTest.log('No customPreview generated');
+ }
+}
diff --git a/deps/v8/test/inspector/runtime/scopes-internal-property-expected.txt b/deps/v8/test/inspector/runtime/scopes-internal-property-expected.txt
new file mode 100644
index 00000000000..c4c9bece400
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/scopes-internal-property-expected.txt
@@ -0,0 +1,80 @@
+Tests that [[Scopes]] of functions and generators only list non-empty scopes of the runtime context chain.
+outerCtx(false)
+ 0: Closure (outerCtx) {captured=1}
+ 1: Global
+outerCtx(true)()
+ 0: Local (gen) {}
+ 1: Closure (outerCtx) {captured=1}
+ 2: Global
+outerNoCtx(false)
+ 0: Global
+outerNoCtx(true)()
+ 0: Local (gen) {}
+ 1: Global
+emptyOuter(false)
+ 0: Global
+emptyOuter(true)()
+ 0: Local (gen) {}
+ 1: Global
+catchOuter(false)
+ 0: Catch {e=1}
+ 1: Global
+catchOuter(true)()
+ 0: Local (gen) {}
+ 1: Catch {e=1}
+ 2: Global
+catchOuterNoCtx(false)
+ 0: Catch {e=1}
+ 1: Global
+catchOuterNoCtx(true)()
+ 0: Local (gen) {}
+ 1: Catch {e=1}
+ 2: Global
+evalOuter(false)
+ 0: Closure (evalOuter) {kind=false, arguments=Arguments(1), ev=1}
+ 1: Global
+evalOuter(true)()
+ 0: Local (gen) {}
+ 1: Closure (evalOuter) {kind=true, arguments=Arguments(1), ev=1}
+ 2: Global
+classOuter(false)
+ 0: Block (classOuter) {C=function}
+ 1: Closure (classOuter) {kind=false}
+ 2: Global
+classOuter(true)()
+ 0: Local (gen) {}
+ 1: Block (classOuter) {C=function}
+ 2: Closure (classOuter) {kind=true}
+ 3: Global
+classOuterNoRef(false)
+ 0: Closure (classOuterNoRef) {kind=false}
+ 1: Global
+classOuterNoRef(true)()
+ 0: Local (gen) {}
+ 1: Closure (classOuterNoRef) {kind=true}
+ 2: Global
+withOuter(false)
+ 0: With Block (withOuter) {w=1}
+ 1: Closure (withOuter) {kind=false}
+ 2: Global
+withOuter(true)()
+ 0: Local (gen) {}
+ 1: With Block (withOuter) {w=1}
+ 2: Closure (withOuter) {kind=true}
+ 3: Global
+innerGen
+ 0: Block (gen) {b=2}
+ 1: Local (gen) {a=1}
+ 2: Global
+modFn
+ 0: Module {m=1}
+ 1: Global
+modGen()
+ 0: Local (gen) {}
+ 1: Module {m=1}
+ 2: Global
+modFnEmpty
+ 0: Global
+modGenEmpty()
+ 0: Local (gen) {}
+ 1: Global
diff --git a/deps/v8/test/inspector/runtime/scopes-internal-property.js b/deps/v8/test/inspector/runtime/scopes-internal-property.js
new file mode 100644
index 00000000000..d133b97b408
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/scopes-internal-property.js
@@ -0,0 +1,114 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Tests that [[Scopes]] of functions and generators only list non-empty ' +
+ 'scopes of the runtime context chain.');
+
+contextGroup.addScript(`
+var g = 'global';
+function outerCtx(kind) {
+ let captured = 1; let notCaptured = 2;
+ { let blk = 3;
+ return kind ? function* gen() { captured; yield 1; }
+ : function fn() { captured; }; }
+}
+function outerNoCtx(kind, p) {
+ let x = 1;
+ { let b = 2;
+ return kind ? function* gen() { yield 1; } : function fn() {}; }
+}
+function emptyOuter(kind) {
+ return kind ? function* gen() {} : function fn() {};
+}
+function catchOuter(kind) {
+ try { throw 1; } catch (e) {
+ return kind ? function* gen() { e; } : function fn() { e; };
+ }
+}
+function catchOuterNoCtx(kind) {
+ try { throw 1; } catch (e) {
+ let q = e;
+ return kind ? function* gen() {} : function fn() {};
+ }
+}
+function evalOuter(kind) {
+ eval('var ev = 1');
+ return kind ? function* gen() { ev; } : function fn() { ev; };
+}
+function classOuter(kind) {
+ class C {
+ static m() { return kind ? function* gen() { C; } : function fn() { C; }; }
+ }
+ return C.m();
+}
+function classOuterNoRef(kind) {
+ class C { static m() { return kind ? function* gen() {} : function fn() {}; } }
+ return C.m();
+}
+function withOuter(kind) {
+ with ({w: 1}) { return kind ? function* gen() { w; } : function fn() { w; }; }
+}
+function innerBlocks() {
+ return function* gen() { let a = 1; { let b = 2; yield b; } };
+}
+var innerGen = innerBlocks()(); innerGen.next();
+//# sourceURL=test.js`);
+
+contextGroup.addModule(`
+export let m = 1;
+globalThis.modGen = function* gen() { m; };
+globalThis.modFn = function fn() { m; };
+`, 'module.js');
+contextGroup.addModule(`
+globalThis.modGenEmpty = function* gen() {};
+globalThis.modFnEmpty = function fn() {};
+`, 'empty-module.js');
+
+function describe(value) {
+ if (value.type === 'function') return 'function';
+ return value.value ?? value.description;
+}
+
+async function logScopes(expression) {
+ const {result: {result: {objectId}}} =
+ await Protocol.Runtime.evaluate({expression});
+ const {result: {internalProperties}} =
+ await Protocol.Runtime.getProperties({objectId});
+ const scopes = internalProperties.find(p => p.name === '[[Scopes]]');
+ const {result: {result: entries}} = await Protocol.Runtime.getProperties(
+ {objectId: scopes.value.objectId, ownProperties: true});
+ InspectorTest.log(expression);
+ for (const entry of entries) {
+ if (!entry.value || entry.name === '__proto__') continue;
+ let line = ` ${entry.name}: ${entry.value.description}`;
+ if (!entry.value.description.startsWith('Global')) {
+ const {result: {result: variables}} = await Protocol.Runtime.getProperties(
+ {objectId: entry.value.objectId, ownProperties: true});
+ line += ' {' +
+ variables
+ .map(v => `${v.name}=${
+ 'value' in v ? describe(v.value) : '<unavailable>'}`)
+ .join(', ') +
+ '}';
+ }
+ InspectorTest.log(line);
+ }
+}
+
+(async function test() {
+ await Protocol.Runtime.enable();
+ for (const f of ['outerCtx', 'outerNoCtx', 'emptyOuter', 'catchOuter',
+ 'catchOuterNoCtx', 'evalOuter', 'classOuter',
+ 'classOuterNoRef', 'withOuter']) {
+ await logScopes(`${f}(false)`);
+ await logScopes(`${f}(true)()`);
+ }
+ await logScopes('innerGen');
+ await logScopes('modFn');
+ await logScopes('modGen()');
+ await logScopes('modFnEmpty');
+ await logScopes('modGenEmpty()');
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/terminate-execution-expected.txt b/deps/v8/test/inspector/runtime/terminate-execution-expected.txt
index ccd85fad3ba..5ce23456d11 100644
--- a/deps/v8/test/inspector/runtime/terminate-execution-expected.txt
+++ b/deps/v8/test/inspector/runtime/terminate-execution-expected.txt
@@ -70,4 +70,22 @@ Terminate execution with pending microtasks
result : {
}
}
+Terminate execution is not allowed for untrusted clients
+{
+ error : {
+ code : -32000
+ message : Runtime.terminateExecution is not allowed for untrusted clients
+ }
+ id : <messageId>
+}
+{
+ id : <messageId>
+ result : {
+ result : {
+ description : 42
+ type : number
+ value : 42
+ }
+ }
+}
Terminate execution does not crash on destroy
diff --git a/deps/v8/test/inspector/runtime/terminate-execution.js b/deps/v8/test/inspector/runtime/terminate-execution.js
index 3fd6b60242c..9a5268f36aa 100644
--- a/deps/v8/test/inspector/runtime/terminate-execution.js
+++ b/deps/v8/test/inspector/runtime/terminate-execution.js
@@ -68,6 +68,14 @@ let {session, contextGroup, Protocol} =
await Protocol.Debugger.resume();
await Protocol.Runtime.disable();
+ InspectorTest.log('Terminate execution is not allowed for untrusted clients');
+ const untrustedSession = contextGroup.connect(/* isFullyTrusted */ false);
+ InspectorTest.logMessage(
+ await untrustedSession.Protocol.Runtime.terminateExecution());
+ InspectorTest.logMessage(
+ await untrustedSession.Protocol.Runtime.evaluate({expression: '42'}));
+ untrustedSession.disconnect();
+
InspectorTest.log('Terminate execution does not crash on destroy');
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({
diff --git a/deps/v8/test/intl/date-format/temporal-cjk-format.js b/deps/v8/test/intl/date-format/temporal-cjk-format.js
index 14dd6f4a2cc..e6590d30787 100644
--- a/deps/v8/test/intl/date-format/temporal-cjk-format.js
+++ b/deps/v8/test/intl/date-format/temporal-cjk-format.js
@@ -24,7 +24,33 @@ assertTemporalMatchesDate("zh-CN", kOptions);
assertTemporalMatchesDate("zh-TW", kOptions);
assertTemporalMatchesDate("ko-KR", kOptions);
assertTemporalMatchesDate("en-US", kOptions);
+assertTemporalMatchesDate("ja-JP-u-ca-japanese", kOptions);
+assertTemporalMatchesDate("zh-CN-u-ca-chinese", kOptions);
+assertTemporalMatchesDate("zh-TW-u-ca-roc", kOptions);
+assertTemporalMatchesDate("ko-KR-u-ca-dangi", kOptions);
assertTemporalMatchesDate("ja-JP", {dateStyle: "long", timeZone: "UTC"});
assertTemporalMatchesDate("zh-CN", {dateStyle: "long", timeZone: "UTC"});
assertTemporalMatchesDate("ja-JP", {dateStyle: "full", timeZone: "UTC"});
+assertTemporalMatchesDate("ja-JP-u-ca-japanese", {dateStyle: "long", timeZone: "UTC"});
+assertTemporalMatchesDate("ja-JP-u-ca-japanese", {
+ era: "long",
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ timeZone: "UTC"
+});
+
+const formatter = new Intl.DateTimeFormat("en-US", {
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ hour: "numeric",
+ timeZone: "UTC",
+});
+
+assertFalse(
+ formatter.formatToParts(kPlainDate).some(
+ ({type}) => type === "hour" || type === "dayPeriod"
+ )
+);
diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status
index 68d825812f7..332a3012bc1 100644
--- a/deps/v8/test/intl/intl.status
+++ b/deps/v8/test/intl/intl.status
@@ -115,4 +115,10 @@
'date-format/temporal-cjk-format': [SKIP],
}], # variant == google3
+################################################################################
+['not temporal', {
+ # Needs temporal:
+ 'date-format/temporal-cjk-format': [SKIP],
+}], # 'not temporal'
+
]
diff --git a/deps/v8/test/intl/regexp-case-equivalence.js b/deps/v8/test/intl/regexp-case-equivalence.js
new file mode 100644
index 00000000000..33da7140c52
--- /dev/null
+++ b/deps/v8/test/intl/regexp-case-equivalence.js
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// Exercise literals, ranges, and backreferences with the same case pairs.
+const pairs = [
+ ['a', 'A', true, true],
+ ['k', '\u212a', false, true],
+ ['s', '\u017f', false, true],
+ ['\u00df', '\u1e9e', false, true],
+ ['\u00b5', '\u03bc', true, true],
+ ['i', '\u0130', false, false],
+ ['I', '\u0131', false, false],
+ ['\u{10400}', '\u{10428}', false, true],
+ ['\ud800', '\ud800', true, true],
+ ['\ud800', '\ud801', false, false],
+];
+
+for (const [a, b, legacy, unicode] of pairs) {
+ for (const [c1, c2] of [[a, b], [b, a]]) {
+ for (const flags of ['i', 'iu', 'iv']) {
+ const expected = flags === 'i' ? legacy : unicode;
+ // Force two-byte subjects even when the pair is entirely Latin1.
+ for (const prefix of ['', '\u2603']) {
+ const literal = new RegExp('^' + prefix + c1 + '$', flags);
+ const backref = new RegExp('^' + prefix + '(' + c1 + ')\\1$', flags);
+ // A legacy character class cannot represent an astral character.
+ const range = flags !== 'i' || c1.length === 1
+ ? new RegExp('^' + prefix + '[' + c1 + '-' + c1 + ']$', flags)
+ : null;
+ assertEquals(expected, literal.test(prefix + c2), literal.toString());
+ assertEquals(expected, backref.test(prefix + c1 + c2),
+ backref.toString());
+ if (range !== null) {
+ assertEquals(expected, range.test(prefix + c2), range.toString());
+ }
+ }
+ }
+ }
+}
+
+for (const flags of ['i', 'iu', 'iv']) {
+ const re = new RegExp('^[a-c\u017f\u00df]$', flags);
+ for (const c of ['a', 'B', 'c', '\u017f', '\u00df']) {
+ assertTrue(re.test(c));
+ }
+ for (const c of ['s', 'S', '\u1e9e']) {
+ assertEquals(flags !== 'i', re.test(c));
+ }
+}
+
+// Sorting must preserve the preference between equivalent alternatives.
+for (const flags of ['i', 'iu', 'iv']) {
+ assertEquals('is', new RegExp('is|I|ix|z', flags).exec('is')[0]);
+}
diff --git a/deps/v8/test/intl/regexp-ignore-case-alternatives.js b/deps/v8/test/intl/regexp-ignore-case-alternatives.js
new file mode 100644
index 00000000000..aefdbd7f288
--- /dev/null
+++ b/deps/v8/test/intl/regexp-ignore-case-alternatives.js
@@ -0,0 +1,57 @@
+// Copyright 2026 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.
+
+// Factoring /i alternatives by common prefix must not equate U+017F and 's'.
+
+assertTrue(/^(?:\u017fa|sb|\u017fc|sd)$/i.test('sb'));
+assertFalse(/^(?:\u017fa|sb|\u017fc|sd)$/i.test('\u017fb'));
+assertTrue(/^(?:\u212aa|kb|\u212ac|kd)$/i.test('Kb'));
+assertFalse(/^(?:\u212aa|kb|\u212ac|kd)$/i.test('\u212ab'));
+assertTrue(/^(?:\u017fa|sb|\u017fc|sd)$/iu.test('\u017fb'));
+
+// A disjunction must match exactly what its alternatives match individually.
+function TestAlternatives(c1, c2, flags) {
+ for (const prefix of ['', 'q']) {
+ const alternatives =
+ [c1 + 'a', c2 + 'b', c1 + 'c', c2 + 'd'].map(a => prefix + a);
+ const re = new RegExp('^(?:' + alternatives.join('|') + ')$', flags);
+ const singles = alternatives.map(a => new RegExp('^' + a + '$', flags));
+ for (const c of [c1, c2]) {
+ for (const suffix of 'abcd') {
+ const s = prefix + c + suffix;
+ assertEquals(singles.some(r => r.test(s)), re.test(s), re + ' ' + s);
+ }
+ }
+ }
+}
+
+// Interesting case-folding equivalence classes, see intl/regress-10248.js.
+const equivalence_classes = [
+ '\u0041\u0061', // Aa (sanity check)
+ '\u004b\u006b\u212a', // KkK
+ '\u0053\u0073\u017f', // Ssſ
+ '\u00b5\u039c\u03bc', // µΜμ
+ '\u00c5\u00e5\u212b', // ÅåÅ
+ '\u00df\u1e9e', // ßẞ
+ '\u03a9\u03c9\u2126', // ΩωΩ
+ '\u0390\u1fd3', // ΐΐ
+ '\u0398\u03b8\u03d1\u03f4', // Θθϑϴ
+ '\u03b0\u1fe3', // ΰΰ
+ '\u1f80\u1f88', // ᾀᾈ
+ '\u1fb3\u1fbc', // ᾳᾼ
+ '\u1fc3\u1fcc', // ῃῌ
+ '\u1ff3\u1ffc', // ῳῼ
+ '\ufb05\ufb06', // ſtst
+];
+
+for (const eclass of equivalence_classes) {
+ for (const c1 of eclass) {
+ for (const c2 of eclass) {
+ if (c1 === c2) continue;
+ for (const flags of ['i', 'iu', 'iv']) {
+ TestAlternatives(c1, c2, flags);
+ }
+ }
+ }
+}
diff --git a/deps/v8/test/intl/regress-10248.js b/deps/v8/test/intl/regress-10248.js
index c1cdc7b42a2..01802afdcd1 100644
--- a/deps/v8/test/intl/regress-10248.js
+++ b/deps/v8/test/intl/regress-10248.js
@@ -37,7 +37,7 @@ function TestAll() {
// Interesting case-folding equivalence classes (as determined by
// ICU's UnicodeSet::closeOver). A class is interesting if it contains
// more than two characters, or if it contains any characters in
-// IgnoreSet or SpecialAddSet as defined in src/regexp/special-case.h.
+// IgnoreSet as defined in src/regexp/special-case.h.
var equivalence_classes = [
'\u0041\u0061', // Aa (sanity check)
'\u004b\u006b\u212a', // KkK
diff --git a/deps/v8/test/intl/regress-10573.js b/deps/v8/test/intl/regress-10573.js
index 4804df004c7..8cfbf7ab671 100644
--- a/deps/v8/test/intl/regress-10573.js
+++ b/deps/v8/test/intl/regress-10573.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-function assertEquals(a,b) { if (a !== b) print("BLAH"); }
-
// See https://tc39.es/ecma262/#sec-runtime-semantics-canonicalize-ch
function Canonicalize(ch) {
var u = ch.toUpperCase();
@@ -27,8 +25,6 @@ function TestEquivalenceClass(eclass) {
assertEquals(backref.test(cc), shouldMatch);
- //TODO(v8:10591): Update expectations for ΐΐ, ΰΰ, and ſtst once
- //case folding is fixed.
assertEquals(backrefUnicode.test(cc), true);
}
}
@@ -43,7 +39,7 @@ function TestAll() {
// Interesting case-folding equivalence classes (as determined by
// ICU's UnicodeSet::closeOver). A class is interesting if it contains
// more than two characters, or if it contains any characters in
-// IgnoreSet or SpecialAddSet as defined in src/regexp/special-case.h.
+// IgnoreSet as defined in src/regexp/special-case.h.
var equivalence_classes = [
'\u0041\u0061', // Aa (sanity check)
'\u004b\u006b\u212a', // KkK
diff --git a/deps/v8/test/mjsunit/compiler/concurrent-string-ext-seq.js b/deps/v8/test/mjsunit/compiler/concurrent-string-ext-seq.js
index fe3068ca925..4810b918f08 100644
--- a/deps/v8/test/mjsunit/compiler/concurrent-string-ext-seq.js
+++ b/deps/v8/test/mjsunit/compiler/concurrent-string-ext-seq.js
@@ -25,22 +25,34 @@ function TestRace(str, f, ext, syncPointName) {
// concatenation.
%BlockAt("ConcurrentConcatenateStrings", 10000);
%PrepareFunctionForOptimization(f);
- f();
+ // Warm up with the string addition path.
+ f(true);
%OptimizeFunctionOnNextCall(f, "concurrent");
- f();
- assertTrue(%WaitUntilBlocked("ConcurrentConcatenateStrings", 10000));
+ // Trigger the compilation; do not use the string addition here since an
+ // allocation might trigger a GC, which would deadlock with the sync point.
+ f(false);
+
+ // Calling assertTrue here would trigger JS allocations and interrupt checks,
+ // causing a deadlock with a GC.
+ let res0 = %WaitUntilBlocked("ConcurrentConcatenateStrings", 10000);
// 3. Move the background thread forward to pause during the actual string
// memory read.
%BlockAt(syncPointName, 10000);
- assertTrue(%Resume("ConcurrentConcatenateStrings"));
- assertTrue(%WaitUntilBlocked(syncPointName, 10000));
+ let res1 = %Resume("ConcurrentConcatenateStrings");
+ let res2 = %WaitUntilBlocked(syncPointName, 10000);
// 4. Unblock the background thread and immediately try to externalize on the
// main thread. The background thread is reading the string, and the main
// thread will safely block until the background read completes.
- assertTrue(%Resume(syncPointName));
+ let res3 = %Resume(syncPointName);
ext(str);
+
+ // Safe to assert now that the background thread is free.
+ assertTrue(res0);
+ assertTrue(res1);
+ assertTrue(res2);
+ assertTrue(res3);
}
// Base length must be >= ConsString::kMinLength to form a ConsString, and
@@ -49,12 +61,12 @@ const kBaseLen = 42;
const str1 = "A".repeat(kBaseLen);
%InternalizeString(str1);
-function f1() { return str1 + "x"; }
+function f1(do_string_op) { if (do_string_op) return str1 + "x"; return 0; }
function externalize1(s) { externalizeString(s); }
TestRace(str1, f1, externalize1, "StringWriteToFlatSeqOneByteString");
const str2 = "\u1234".repeat(kBaseLen);
%InternalizeString(str2);
-function f2() { return str2 + "x"; }
+function f2(do_string_op) { if (do_string_op) return str2 + "x"; return 0; }
function externalize2(s) { externalizeString(s); }
TestRace(str2, f2, externalize2, "StringWriteToFlatSeqTwoByteString");
diff --git a/deps/v8/test/mjsunit/compiler/define-const-data-field-class-field.js b/deps/v8/test/mjsunit/compiler/define-const-data-field-class-field.js
new file mode 100644
index 00000000000..af62b64be0f
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/define-const-data-field-class-field.js
@@ -0,0 +1,158 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbofan
+
+// A DefineNamedOwnProperty into a const field may only keep the field const
+// when the field still holds the uninitialized value, i.e. when the define is
+// the initializing store of an object literal. A define into an already
+// initialized const field must generalize the field to mutable.
+
+// Class field initializer, run on an already initialized object via return
+// override.
+(function TestDefineIntoInitializedConstField() {
+ function H1(a, b) { this.otherProp = a; this.myProp = b;}
+ function H2(a, b) { this.otherProp = a; this.myProp = b;}
+
+ const first = {};
+ const second = {};
+ const holder = new H1(1, first);
+
+ class Base { constructor(o) { return o; } }
+
+ // This function is just used for feeding map information into the optimized function.
+ function feedMap(o) {
+ return o.otherProp;
+ }
+ %PrepareFunctionForOptimization(feedMap);
+
+ // Warm up with both H1 and H2.
+ const dummyH1 = new H1(1, second);
+ const dummyH2 = new H2(1, second);
+ feedMap(dummyH1);
+ feedMap(dummyH2);
+
+ class D extends Base { myProp = (feedMap(this), second); }
+
+ function define(o) {
+ new D(o);
+ }
+ %PrepareFunctionForOptimization(D);
+ %PrepareFunctionForOptimization(define);
+
+ // Warm up define only with H2.
+ for (let i = 0; i < 20; i++) {
+ define(new H2(1, second));
+ }
+
+ %OptimizeFunctionOnNextCall(define);
+ define(new H2(1, second));
+ assertOptimized(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H1.
+ define(holder);
+ assertSame(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
+
+// Same, but the const field has Smi representation.
+(function TestDefineIntoInitializedConstFieldSmi() {
+ function H1(a, b) { this.otherProp = a; this.myProp = b;}
+ function H2(a, b) { this.otherProp = a; this.myProp = b;}
+
+ const first = 10;
+ const second = 20;
+ const holder = new H1(1, first);
+
+ class Base { constructor(o) { return o; } }
+
+ // This function is just used for feeding map information into the optimized function.
+ function feedMap(o) {
+ return o.otherProp;
+ }
+ %PrepareFunctionForOptimization(feedMap);
+
+ // Warm up with both H1 and H2.
+ const dummyH1 = new H1(1, second);
+ const dummyH2 = new H2(1, second);
+ feedMap(dummyH1);
+ feedMap(dummyH2);
+
+ class D extends Base { myProp = (feedMap(this), second); }
+
+ function define(o) {
+ new D(o);
+ }
+ %PrepareFunctionForOptimization(D);
+ %PrepareFunctionForOptimization(define);
+
+ // Warm up define only with H2.
+ for (let i = 0; i < 20; i++) {
+ define(new H2(1, second));
+ }
+
+ %OptimizeFunctionOnNextCall(define);
+ define(new H2(1, second));
+ assertOptimized(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H1.
+ define(holder);
+ assertSame(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
+
+// Same, but the const field has Double representation.
+(function TestDefineIntoInitializedConstFieldDouble() {
+ function H1(a, b) { this.otherProp = a; this.myProp = b;}
+ function H2(a, b) { this.otherProp = a; this.myProp = b;}
+
+ const first = 1.5;
+ const second = 2.5;
+ const holder = new H1(1, first);
+
+ class Base { constructor(o) { return o; } }
+
+ // This function is just used for feeding map information into the optimized function.
+ function feedMap(o) {
+ return o.otherProp;
+ }
+ %PrepareFunctionForOptimization(feedMap);
+
+ // Warm up with both H1 and H2.
+ const dummyH1 = new H1(1, second);
+ const dummyH2 = new H2(1, second);
+ feedMap(dummyH1);
+ feedMap(dummyH2);
+
+ class D extends Base { myProp = (feedMap(this), second); }
+
+ function define(o) {
+ new D(o);
+ }
+ %PrepareFunctionForOptimization(D);
+ %PrepareFunctionForOptimization(define);
+
+ // Warm up define only with H2.
+ for (let i = 0; i < 20; i++) {
+ define(new H2(1, second));
+ }
+
+ %OptimizeFunctionOnNextCall(define);
+ define(new H2(1, second));
+ assertOptimized(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H1.
+ define(holder);
+ assertSame(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-331909453.js b/deps/v8/test/mjsunit/compiler/regress-331909453.js
index d982af3d0ab..cbdb3e7b6b9 100644
--- a/deps/v8/test/mjsunit/compiler/regress-331909453.js
+++ b/deps/v8/test/mjsunit/compiler/regress-331909453.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --expose-fast-api
+// Flags: --allow-natives-syntax --expose-fast-api --turbofan
const fast_c_api = new d8.test.FastCAPI();
diff --git a/deps/v8/test/mjsunit/compiler/regress-561186948.js b/deps/v8/test/mjsunit/compiler/regress-561186948.js
new file mode 100644
index 00000000000..bff485c7af0
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-561186948.js
@@ -0,0 +1,26 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+"use strict";
+
+function* gen() {
+ yield 1;
+}
+
+function foo(x) {
+ return [gen.call(x)];
+}
+
+%PrepareFunctionForOptimization(gen);
+%PrepareFunctionForOptimization(foo);
+
+let arr = foo(1);
+%PretenureAllocationSite(arr);
+gc({type: 'minor'});
+foo(1);
+
+%OptimizeFunctionOnNextCall(foo);
+foo(-1);
diff --git a/deps/v8/test/mjsunit/compiler/regress-569659194-1.js b/deps/v8/test/mjsunit/compiler/regress-569659194-1.js
new file mode 100644
index 00000000000..76d1084946c
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-569659194-1.js
@@ -0,0 +1,44 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+function makeGenerator() {
+ return function* () {};
+}
+
+// %GeneratorPrototype% starts in fast-properties mode from the snapshot, with
+// is_prototype_map() == true and should_be_fast_prototype_map() == false.
+const generatorPrototype = Object.getPrototypeOf(makeGenerator()).prototype;
+generatorPrototype.doubleProp = 1.5;
+
+function foo(obj, gen) {
+ // Access an in-object property first so TurboFan emits CheckMaps(obj).
+ obj.next = 1;
+ // Calling an uninitialized generator closure normalizes generatorPrototype
+ // from fast properties (PropertyArray) to dictionary mode (NameDictionary).
+ gen();
+ // Because JSCreateGeneratorObject was marked kNoWrite, LoadElimination
+ // eliminated the CheckMaps(obj) before this out-of-object double store.
+ obj.doubleProp = 3.5;
+}
+
+// Warm up with two closures that already have a custom .prototype so that:
+// 1. The call site in foo() is polymorphic over closures (not specialized to a
+// single HeapConstant closure) and lowers to JSCreateGeneratorObject.
+// 2. Initializing their initial_map does not touch generatorPrototype.
+const gen1 = makeGenerator();
+const gen2 = makeGenerator();
+gen1.prototype = {};
+gen2.prototype = {};
+
+%PrepareFunctionForOptimization(foo);
+%PrepareFunctionForOptimization(gen1);
+foo(generatorPrototype, gen1);
+foo(generatorPrototype, gen2);
+
+%OptimizeFunctionOnNextCall(foo);
+const freshGen = makeGenerator();
+foo(generatorPrototype, freshGen);
+assertEquals(3.5, generatorPrototype.doubleProp);
diff --git a/deps/v8/test/mjsunit/compiler/regress-569659194-2.js b/deps/v8/test/mjsunit/compiler/regress-569659194-2.js
new file mode 100644
index 00000000000..49efb73059a
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-569659194-2.js
@@ -0,0 +1,37 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+function makeGenerator() {
+ return function* () {};
+}
+
+// %GeneratorPrototype% starts in fast-properties mode with a stable map.
+const generatorPrototype = Object.getPrototypeOf(makeGenerator()).prototype;
+
+function foo(gen) {
+ // Calling an uninitialized generator closure normalizes generatorPrototype,
+ // which invalidates its stable map and triggers lazy deoptimization of foo().
+ gen();
+ // Accessing generatorPrototype as a HeapConstant installs a compilation
+ // dependency (DependOnStableMap) on generatorPrototype's map rather than
+ // emitting a CheckMaps node.
+ generatorPrototype.next = 1;
+}
+
+const gen1 = makeGenerator();
+const gen2 = makeGenerator();
+gen1.prototype = {};
+gen2.prototype = {};
+
+%PrepareFunctionForOptimization(foo);
+%PrepareFunctionForOptimization(gen1);
+foo(gen1);
+foo(gen2);
+
+%OptimizeFunctionOnNextCall(foo);
+const freshGen = makeGenerator();
+foo(freshGen);
+assertEquals(1, generatorPrototype.next);
diff --git a/deps/v8/test/mjsunit/compiler/regress-569659194-3.js b/deps/v8/test/mjsunit/compiler/regress-569659194-3.js
new file mode 100644
index 00000000000..0b30f10d2ed
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-569659194-3.js
@@ -0,0 +1,64 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+function makeGenerator() {
+ return function* () {};
+}
+
+// Even if %GeneratorPrototype% starts in dictionary mode or with
+// should_be_fast_prototype_map() == true, iterating over a generator instance
+// ensures %GeneratorPrototype% is in fast mode with
+// should_be_fast_prototype_map() == true.
+for (let _ in (function* () {})()) {}
+
+const generatorPrototype = Object.getPrototypeOf(makeGenerator()).prototype;
+generatorPrototype[0] = 1;
+
+// Reconfiguring a field from Smi to Double on a detached prototype root map
+// normalizes generatorPrototype to dictionary mode (NameDictionary) without
+// clearing should_be_fast_prototype_map() on its PrototypeInfo.
+generatorPrototype.x = 1;
+generatorPrototype.x = 1.5;
+
+function foo(obj, gen) {
+ // Emit CheckMaps(obj, [dictionary_map]) before gen().
+ obj[0];
+ // Calling an uninitialized generator closure invokes
+ // JSObject::OptimizeAsPrototype(generatorPrototype), which sees
+ // should_be_fast_prototype_map() == true && !HasFastProperties() and calls
+ // JSObject::MigrateSlowToFast(generatorPrototype), replacing its
+ // NameDictionary with a PropertyArray.
+ gen();
+ // Without the fix, LoadElimination eliminated CheckMaps(obj, [dictionary_map])
+ // before LoadDictionaryField, which then read the new PropertyArray as if it
+ // were a NameDictionary.
+ return obj.x;
+}
+
+const gen1 = makeGenerator();
+const gen2 = makeGenerator();
+gen1.prototype = {};
+gen2.prototype = {};
+
+%PrepareFunctionForOptimization(foo);
+%PrepareFunctionForOptimization(gen1);
+foo(generatorPrototype, gen1);
+foo(generatorPrototype, gen2);
+
+%OptimizeFunctionOnNextCall(foo);
+
+// Populate dictionary properties (which does not change generatorPrototype's
+// dictionary map) so that after MigrateSlowToFast packs all properties into a
+// PropertyArray, every NameDictionary entry offset [6 + 3 * i] in the
+// PropertyArray contains a valid fake dictionary entry ["x", "corrupted", 0].
+for (let i = 0; i < 48; i += 3) {
+ generatorPrototype['p' + i] = 'x';
+ generatorPrototype['p' + (i + 1)] = 'corrupted';
+ generatorPrototype['p' + (i + 2)] = 0;
+}
+
+const freshGen = makeGenerator();
+assertEquals(1.5, foo(generatorPrototype, freshGen));
diff --git a/deps/v8/test/mjsunit/compiler/regress-crbug-1201011.js b/deps/v8/test/mjsunit/compiler/regress-crbug-1201011.js
index 9086fa794ba..25f45c0881d 100644
--- a/deps/v8/test/mjsunit/compiler/regress-crbug-1201011.js
+++ b/deps/v8/test/mjsunit/compiler/regress-crbug-1201011.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --turbo-fast-api-calls --expose-fast-api
+// Flags: --turbo-fast-api-calls --expose-fast-api --turbofan
const fast_c_api = new d8.test.FastCAPI();
function foo(obj) {
diff --git a/deps/v8/test/mjsunit/compiler/regress-crbug-1201057.js b/deps/v8/test/mjsunit/compiler/regress-crbug-1201057.js
index 4315175ad54..5cd1e0da256 100644
--- a/deps/v8/test/mjsunit/compiler/regress-crbug-1201057.js
+++ b/deps/v8/test/mjsunit/compiler/regress-crbug-1201057.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --turbo-fast-api-calls --expose-fast-api
+// Flags: --turbo-fast-api-calls --expose-fast-api --turbofan
const fast_c_api = new d8.test.FastCAPI();
const fast_obj = Object.create(fast_c_api);
diff --git a/deps/v8/test/mjsunit/compiler/regress-crbug-1201082.js b/deps/v8/test/mjsunit/compiler/regress-crbug-1201082.js
index 142d0d7861f..8695a582f8e 100644
--- a/deps/v8/test/mjsunit/compiler/regress-crbug-1201082.js
+++ b/deps/v8/test/mjsunit/compiler/regress-crbug-1201082.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --turbo-fast-api-calls --expose-fast-api
+// Flags: --turbo-fast-api-calls --expose-fast-api --turbofan
const fast_c_api = new d8.test.FastCAPI();
function foo(obj) {
diff --git a/deps/v8/test/mjsunit/compiler/regress-crbug-1457532.js b/deps/v8/test/mjsunit/compiler/regress-crbug-1457532.js
index 42e97dc1f2f..108ce0ab730 100644
--- a/deps/v8/test/mjsunit/compiler/regress-crbug-1457532.js
+++ b/deps/v8/test/mjsunit/compiler/regress-crbug-1457532.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --expose-fast-api
+// Flags: --expose-fast-api --turbofan
const capi = new d8.test.FastCAPI();
diff --git a/deps/v8/test/mjsunit/compiler/script-context-specialization.js b/deps/v8/test/mjsunit/compiler/script-context-specialization.js
new file mode 100644
index 00000000000..9486e393198
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/script-context-specialization.js
@@ -0,0 +1,58 @@
+// Copyright 2026 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.
+
+// Flags: --always-specialize-for-script-context --turbofan
+// Flags: --allow-natives-syntax
+
+const scriptConst = 42;
+
+function createClosure() {
+ return function foo() {
+ %TurbofanStaticAssert(scriptConst == 42);
+ return scriptConst;
+ };
+}
+
+// Create the closure twice to avoid function context specialization.
+const f1 = createClosure();
+const f2 = createClosure();
+
+%PrepareFunctionForOptimization(f1);
+assertEquals(42, f1());
+%OptimizeFunctionOnNextCall(f1);
+assertEquals(42, f1());
+assertOptimized(f1);
+
+%PrepareFunctionForOptimization(f2);
+assertEquals(42, f2());
+%OptimizeFunctionOnNextCall(f2);
+assertEquals(42, f2());
+assertOptimized(f2);
+
+function createClosure2() {
+ return function bar() {
+ %TurbofanStaticAssert(scriptConst == 42);
+ return scriptConst;
+ };
+}
+
+// Create and optimize the first closure (with function context specialization),
+// then create and optimize a second closure (transitioning from
+// one_closure_cell to many_closures_cell and recompiling without function
+// context specialization).
+const g1 = createClosure2();
+%PrepareFunctionForOptimization(g1);
+assertEquals(42, g1());
+%OptimizeFunctionOnNextCall(g1);
+assertEquals(42, g1());
+assertOptimized(g1);
+
+const g2 = createClosure2();
+%PrepareFunctionForOptimization(g2);
+assertEquals(42, g2());
+%OptimizeFunctionOnNextCall(g2);
+assertEquals(42, g2());
+assertOptimized(g2);
+assertEquals(42, g1());
+assertOptimized(g1);
diff --git a/deps/v8/test/mjsunit/compiler/typed-array-length-as-number.js b/deps/v8/test/mjsunit/compiler/typed-array-length-as-number.js
index 71ef0f4bd45..c73857831aa 100644
--- a/deps/v8/test/mjsunit/compiler/typed-array-length-as-number.js
+++ b/deps/v8/test/mjsunit/compiler/typed-array-length-as-number.js
@@ -4,7 +4,7 @@
//
// Flags: --allow-natives-syntax --turbofan
// Flags: --no-turbolev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
function foo(size) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/compiler/typed-array-length-iteration.js b/deps/v8/test/mjsunit/compiler/typed-array-length-iteration.js
index 4871e8e14fc..b775e6e8c08 100644
--- a/deps/v8/test/mjsunit/compiler/typed-array-length-iteration.js
+++ b/deps/v8/test/mjsunit/compiler/typed-array-length-iteration.js
@@ -4,7 +4,7 @@
//
// Flags: --allow-natives-syntax --turbofan
// Flags: --no-turbolev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
function foo(size) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/d8/d8-test-access-checked-interceptor-object.js b/deps/v8/test/mjsunit/d8/d8-test-access-checked-interceptor-object.js
new file mode 100644
index 00000000000..4eb91ab61b8
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-test-access-checked-interceptor-object.js
@@ -0,0 +1,22 @@
+// Copyright 2026 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.
+
+// The interceptor is invoked on failed access checks (e.g. cross-origin
+// window/location handling).
+{
+ let obj = d8.test.createAccessCheckedInterceptorObject(false,
+ () => "intercepted-on-denied");
+ assertEquals("intercepted-on-denied", obj.a);
+ d8.test.setAccessPolicy(obj, true);
+ obj.a = 42;
+ assertEquals(42, obj.a);
+}
+
+// Input validation.
+assertThrows(() => d8.test.createAccessCheckedInterceptorObject(), Error);
+assertThrows(() => d8.test.createAccessCheckedInterceptorObject(true), Error);
+assertThrows(() =>
+ d8.test.createAccessCheckedInterceptorObject(true, "notfunction"), Error);
+assertThrows(() => d8.test.createAccessCheckedInterceptorObject(123, () => {}),
+ Error);
diff --git a/deps/v8/test/mjsunit/d8/d8-test-special-object.js b/deps/v8/test/mjsunit/d8/d8-test-special-object.js
deleted file mode 100644
index d3fac5f37c8..00000000000
--- a/deps/v8/test/mjsunit/d8/d8-test-special-object.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2026 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.
-
-// 1. Empty options object creates an API object without interceptor or access
-// check.
-{
- let obj = d8.test.createSpecialObject({});
- obj.a = 42;
- assertEquals(42, obj.a);
-}
-
-// 2. Options with interceptor.
-{
- let obj = d8.test.createSpecialObject({
- interceptor: () => "intercepted",
- });
- assertEquals("intercepted", obj.a);
-}
-
-// 3. Options with accessCheck.
-{
- let obj = d8.test.createSpecialObject({
- accessCheck: true,
- });
- obj.a = 42;
- assertEquals(42, obj.a);
- d8.test.setAccessPolicy(obj, false);
- assertThrows(() => obj.a, TypeError);
-}
-
-// 4. Options with both interceptor and accessCheck:
-// The interceptor is invoked on failed access checks (e.g. cross-origin
-// window/location handling).
-{
- let obj = d8.test.createSpecialObject({
- interceptor: () => "intercepted-on-denied",
- accessCheck: false,
- });
- assertEquals("intercepted-on-denied", obj.a);
- d8.test.setAccessPolicy(obj, true);
- obj.a = 42;
- assertEquals(42, obj.a);
-}
-
-// 5. Input validation.
-assertThrows(() => d8.test.createSpecialObject(), Error);
-assertThrows(() => d8.test.createSpecialObject(123), Error);
-assertThrows(() => d8.test.createSpecialObject("bad"), Error);
-assertThrows(() => d8.test.createSpecialObject({ interceptor: 123 }), Error);
-assertThrows(() => d8.test.createSpecialObject({ accessCheck: 123 }), Error);
-assertThrows(() => d8.test.createSpecialObject({ accessCheck: "bad" }), Error);
-assertThrows(() => d8.test.createSpecialObject({ accessCheck: () => true }), Error);
diff --git a/deps/v8/test/mjsunit/empirical_max_arraybuffer.js b/deps/v8/test/mjsunit/empirical_max_arraybuffer.js
index cacefd46928..84863f88436 100644
--- a/deps/v8/test/mjsunit/empirical_max_arraybuffer.js
+++ b/deps/v8/test/mjsunit/empirical_max_arraybuffer.js
@@ -2,25 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
let kMax31BitSmi = (1 << 30) - 1;
let k1MiB = 1 * 1024 * 1024;
let k1GiB = 1 * 1024 * 1024 * 1024;
let k4GiB = 4 * k1GiB;
-let kPageSize = 65536;
-let kMaxArrayBufferSize = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB
+let kMaxBufferSize = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB
let kStrideLength = 65536;
(function Test() {
+ if (typeof WebAssembly === 'undefined') return;
var buffer;
try {
- buffer = new ArrayBuffer(kMaxArrayBufferSize);
+ let kPages = kMaxBufferSize / kPageSize;
+ let memory = new WebAssembly.Memory({initial: kPages, maximum: kPages});
+ buffer = memory.buffer;
} catch (e) {
print("OOM: sorry, best effort max array buffer size test!");
return;
}
print("Allocated " + buffer.byteLength + " bytes");
- assertEquals(kMaxArrayBufferSize, buffer.byteLength);
+ assertEquals(kMaxBufferSize, buffer.byteLength);
function probe(view, stride, f) {
print("--------------------");
@@ -37,11 +41,11 @@ let kStrideLength = 65536;
{
// Make an uint32 view and probe it.
let elemSize = 4;
- let viewSize = kMaxArrayBufferSize / elemSize;
+ let viewSize = kMaxBufferSize / elemSize;
// TODO(titzer): view sizes are limited to 31 bit SMIs. fix.
if (viewSize <= kMax31BitSmi) {
let uint32 = new Uint32Array(buffer);
- assertEquals(kMaxArrayBufferSize / elemSize, uint32.length);
+ assertEquals(kMaxBufferSize / elemSize, uint32.length);
probe(uint32, kStrideLength / elemSize,
i => (0xaabbccee ^ ((i >> 11) * 0x110005)) >>> 0);
}
@@ -50,11 +54,11 @@ let kStrideLength = 65536;
{
// Make an uint16 view and probe it.
let elemSize = 2;
- let viewSize = kMaxArrayBufferSize / elemSize;
+ let viewSize = kMaxBufferSize / elemSize;
// TODO(titzer): view sizes are limited to 31 bit SMIs. fix.
if (viewSize <= kMax31BitSmi) {
let uint16 = new Uint16Array(buffer);
- assertEquals(kMaxArrayBufferSize / elemSize, uint16.length);
+ assertEquals(kMaxBufferSize / elemSize, uint16.length);
probe(uint16, kStrideLength / elemSize,
i => (0xccee ^ ((i >> 11) * 0x110005)) & 0xFFFF);
}
@@ -63,11 +67,11 @@ let kStrideLength = 65536;
{
// Make an uint8 view and probe it.
let elemSize = 1;
- let viewSize = kMaxArrayBufferSize / elemSize;
+ let viewSize = kMaxBufferSize / elemSize;
// TODO(titzer): view sizes are limited to 31 bit SMIs. fix.
if (viewSize <= kMax31BitSmi) {
let uint8 = new Uint8Array(buffer);
- assertEquals(kMaxArrayBufferSize / elemSize, uint8.length);
+ assertEquals(kMaxBufferSize / elemSize, uint8.length);
probe(uint8, kStrideLength / elemSize,
i => (0xee ^ ((i >> 11) * 0x05)) & 0xFF);
}
@@ -76,11 +80,11 @@ let kStrideLength = 65536;
{
// Make a float64 view and probe it.
let elemSize = 8;
- let viewSize = kMaxArrayBufferSize / elemSize;
+ let viewSize = kMaxBufferSize / elemSize;
// TODO(titzer): view sizes are limited to 31 bit SMIs. fix.
if (viewSize <= kMax31BitSmi) {
let float64 = new Float64Array(buffer);
- assertEquals(kMaxArrayBufferSize / elemSize, float64.length);
+ assertEquals(kMaxBufferSize / elemSize, float64.length);
probe(float64, kStrideLength / elemSize,
i => 0xaabbccee ^ ((i >> 11) * 0x110005));
}
@@ -89,11 +93,11 @@ let kStrideLength = 65536;
{
// Make a float32 view and probe it.
let elemSize = 4;
- let viewSize = kMaxArrayBufferSize / elemSize;
+ let viewSize = kMaxBufferSize / elemSize;
// TODO(titzer): view sizes are limited to 31 bit SMIs. fix.
if (viewSize <= kMax31BitSmi) {
let float32 = new Float32Array(buffer);
- assertEquals(kMaxArrayBufferSize / elemSize, float32.length);
+ assertEquals(kMaxBufferSize / elemSize, float32.length);
probe(float32, kStrideLength / elemSize,
i => Math.fround(0xaabbccee ^ ((i >> 11) * 0x110005)));
}
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-maglev-no-elements-protector-invalidated.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-maglev-no-elements-protector-invalidated.js
index 1f8a5c46e8f..5a7d4eb06f4 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-maglev-no-elements-protector-invalidated.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-maglev-no-elements-protector-invalidated.js
@@ -21,10 +21,10 @@ assertEquals([1, undefined, 3], testForOf([1, , 3]));
%OptimizeMaglevOnNextCall(testForOf);
assertEquals([1, undefined, 3], testForOf([1, , 3]));
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Invalidate NoElementsProtector after optimizing.
Object.prototype[1] = 'element';
assertEquals([1, 'element', 3], testForOf([1, , 3]));
-assertFalse(isMaglevved(testForOf));
+assertNotMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-custom-prototype.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-custom-prototype.js
index da9df454a5f..9b421c167f6 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-custom-prototype.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-custom-prototype.js
@@ -31,6 +31,6 @@ wrapper();
%OptimizeMaglevOnNextCall(wrapper);
let res = wrapper();
-assertTrue(isMaglevved(wrapper));
+assertMaglevved(wrapper);
assertEquals([1, 'element', 3], res);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-eager-next-call.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-eager-next-call.js
index 06aab908872..ace8623261c 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-eager-next-call.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-eager-next-call.js
@@ -45,7 +45,7 @@ testForOfFallbackToCSA(iterA);
iterA.iterObj.count = 0;
testForOfFallbackToCSA(iterA);
-assertTrue(isMaglevved(testForOfFallbackToCSA));
+assertMaglevved(testForOfFallbackToCSA);
// Now trigger the deopt.
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-elements-kinds.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-elements-kinds.js
index 0c59492c02a..0b2d447aea8 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-elements-kinds.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-elements-kinds.js
@@ -41,12 +41,12 @@ function testKind(arr, expected_results, unexpected_arr, expected_unexpected_res
%OptimizeMaglevOnNextCall(foo);
assertEquals(expected_results, foo(arr));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
if (unexpected_arr) {
assertEquals(expected_unexpected_results, foo(unexpected_arr));
// Should deopt!
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
}
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-iterated-map-check.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-iterated-map-check.js
index 14b47cd4903..3a5d5f57190 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-iterated-map-check.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-iterated-map-check.js
@@ -30,7 +30,7 @@ testForOf([1, 2, 3], null);
%OptimizeMaglevOnNextCall(testForOf);
testForOf([1, 2, 3], null);
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Run with an array that we will transition during iteration.
let transitionMe = [1, 2, 3];
@@ -44,4 +44,4 @@ let results = testForOf(transitionMe, transitionMe);
assertEquals(results, [1, 1.5, 3]);
// It should have deoptimized because the map changed.
-assertFalse(isMaglevved(testForOf));
+assertNotMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-map-check.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-map-check.js
index af3266b0e03..453a2452863 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-map-check.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-map-check.js
@@ -28,7 +28,7 @@ testForOf([1, 2, 3]);
%OptimizeMaglevOnNextCall(testForOf);
testForOf([1, 2, 3]);
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Create a fake itertor. Its next method is JSArrayIterator::next, but it is
// not a JSArrayIterator.
@@ -38,4 +38,4 @@ let fake = {
};
assertThrows(() => testForOf(fake), TypeError);
-assertFalse(isMaglevved(testForOf));
+assertNotMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-megamorphic.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-megamorphic.js
index 7a2d3562bee..ff7d15633bf 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-megamorphic.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-megamorphic.js
@@ -51,9 +51,9 @@ assertEquals([1.1, undefined, 3.3], testForOf(a1));
// Megamorphic iterated_object_feedback means TryReduceArrayIteratorForOfNext
// bails out and the generic fallback is used. No deopt expected.
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Verify correct results via the fallback path.
assertEquals([1.1, undefined, 3.3], testForOf(a2));
assertEquals([1.1, undefined, 3.3], testForOf(a3));
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-iterator-from-another-object.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-iterator-from-another-object.js
index ddc22e81742..f8f91bbe42b 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-iterator-from-another-object.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-iterator-from-another-object.js
@@ -33,7 +33,7 @@ assertEquals([3, 4, 5], test1(ta1));
%OptimizeMaglevOnNextCall(test1);
assertEquals([3, 4, 5], test1(ta1));
-assertTrue(isMaglevved(test1));
+assertMaglevved(test1);
// Way 2: Iterator for TypedArray used on Array.
function test2(iterable) {
@@ -57,4 +57,4 @@ assertEquals([44, 55, 66], test2(arr2));
%OptimizeMaglevOnNextCall(test2);
assertEquals([44, 55, 66], test2(arr2));
-assertTrue(isMaglevved(test2));
+assertMaglevved(test2);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-next.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-next.js
index bf02dbfe185..104167894a2 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-next.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-monkey-patch-next.js
@@ -37,11 +37,11 @@ function create_iterator() {
%PrepareFunctionForOptimization(foo);
assertEquals([100], foo(create_iterator()));
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
assertEquals([100], foo(create_iterator()));
%OptimizeMaglevOnNextCall(foo);
assertEquals([100], foo(create_iterator()));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-no-elements-protector-already-invalid.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-no-elements-protector-already-invalid.js
index d0e7ca4f048..0d21a6e10b7 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-no-elements-protector-already-invalid.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-no-elements-protector-already-invalid.js
@@ -31,4 +31,4 @@ assertEquals([1, 'element', 3], testForOf([1, , 3]));
%OptimizeMaglevOnNextCall(testForOf);
assertEquals([1, 'element', 3], testForOf([1, , 3]));
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-non-array-object.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-non-array-object.js
index b5ae651ef35..d94c35d6264 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-non-array-object.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-non-array-object.js
@@ -28,7 +28,7 @@ assertEquals([1, 2, 3], testForOf([1, 2, 3]));
%OptimizeMaglevOnNextCall(testForOf);
assertEquals([1, 2, 3], testForOf([1, 2, 3]));
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Now create a non-array object with fast elements
const nonArray = {};
@@ -43,7 +43,7 @@ const iter1 = Array.prototype.values.call(nonArray);
assertEquals(['a', 'b'], testForOf(iter1));
// Deopted because we iterated something else than an array.
-assertFalse(isMaglevved(testForOf));
+assertNotMaglevved(testForOf);
// After deopt, feedback is polymorphic (array map + non-array map), so
// recompilation uses the generic fallback path and handles both without deopt.
@@ -53,4 +53,4 @@ assertEquals([1, 2, 3], testForOf([1, 2, 3]));
const iter2 = Array.prototype.values.call(nonArray);
assertEquals(['a', 'b'], testForOf(iter2));
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-polymorphic.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-polymorphic.js
index 2221d9aad1d..847d52c40d8 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-polymorphic.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-polymorphic.js
@@ -28,9 +28,9 @@ foo(doubleArray);
%OptimizeMaglevOnNextCall(foo);
assertEquals(6, foo(smiArray));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Run double array. It should NOT deoptimize now because we
// support polymorphic feedback!
assertEquals(7.5, foo(doubleArray));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-protector.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-protector.js
index 6c91effdc5e..0e46de79d91 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-protector.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-protector.js
@@ -28,7 +28,7 @@ testForOf([1, 2, 3]);
%OptimizeMaglevOnNextCall(testForOf);
testForOf([1, 2, 3]);
-assertTrue(isMaglevved(testForOf));
+assertMaglevved(testForOf);
// Now monkey-patch %ArrayIteratorPrototype%.next
let proto = Object.getPrototypeOf([][Symbol.iterator]());
@@ -42,7 +42,7 @@ proto.next = function() {
testForOf([1, 2, 3]);
assertTrue(called);
-assertFalse(isMaglevved(testForOf));
+assertNotMaglevved(testForOf);
// Restore
proto.next = original_next;
diff --git a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-typed-array.js b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-typed-array.js
index f7e23af8d4f..412c7a8c7a4 100644
--- a/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-typed-array.js
+++ b/deps/v8/test/mjsunit/es6/for-of-array-iterator-optimization-maglev-typed-array.js
@@ -37,4 +37,4 @@ assertEquals(
testForOfTypedArray(new Uint8Array([1, 2, 3, 4, 5]))
);
-assertTrue(isMaglevved(testForOfTypedArray));
+assertMaglevved(testForOfTypedArray);
diff --git a/deps/v8/test/mjsunit/es6/super.js b/deps/v8/test/mjsunit/es6/super.js
index a747fed33ce..88cfea36e1b 100644
--- a/deps/v8/test/mjsunit/es6/super.js
+++ b/deps/v8/test/mjsunit/es6/super.js
@@ -2257,3 +2257,21 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44);
assertThrows(Derived.prototype.test, ReferenceError);
assertEquals(1, i);
})();
+
+(function TestDeleteSuperPropertyWithUninitializedThis() {
+ var keyEvaluated = false;
+ var baseCalled = false;
+ class Base {
+ constructor() {
+ baseCalled = true;
+ }
+ }
+ class Derived extends Base {
+ constructor() {
+ delete super[(keyEvaluated = true, super(), 0)];
+ }
+ }
+ assertThrows(() => new Derived(), ReferenceError);
+ assertFalse(keyEvaluated);
+ assertFalse(baseCalled);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/dynamic-code-brand-checks.js b/deps/v8/test/mjsunit/harmony/dynamic-code-brand-checks.js
new file mode 100644
index 00000000000..1679909d6e6
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/dynamic-code-brand-checks.js
@@ -0,0 +1,81 @@
+// Copyright 2026 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.
+//
+// Flags: --allow-natives-syntax
+
+// Tests for Dynamic Code Brand Checks in CreateDynamicFunction
+// (builtins-function.cc). These tests verify the HostGetCodeForEval-style
+// fallback-to-ToString behavior when no embedder callback is installed,
+// and the codegen_allowed rejection path via %DisallowCodegenFromStrings.
+// The callback's HostGetCodeForEval-style code-substitution path is
+// covered in more detail via cctest, since installing a callback that
+// distinguishes between argument shapes isn't possible from pure JS.
+
+(function TestNormalFunctionConstructorStillWorks() {
+ const f = new Function("a", "b", "return a + b;");
+ assertEquals(3, f(1, 2));
+
+ const g = new (function*(){}).constructor("a", "yield a;");
+ assertEquals(5, g(5).next().value);
+
+ const af = new (async function(){}).constructor("a", "return a;");
+ assertInstanceof(af(7), Promise);
+})();
+
+// --- Zero-argument Function constructor (regression test) ---
+//
+// `new Function()` passes zero arguments, so there is no body argument
+// at all. This must not be confused with the receiver (the constructor
+// itself), which sits at BuiltinArguments index 0.
+(function TestZeroArgumentFunctionConstructorHasEmptyBody() {
+ const f = new Function();
+ assertEquals(undefined, f());
+ assertTrue(f.toString().includes("anonymous"));
+})();
+
+// Fallback to ToString when no embedder callback is installed
+(function TestObjectArgumentFallsBackToToString() {
+ // With no embedder callback installed, HostGetCodeForEval has no
+ // effect, so object arguments must fall back to ToString().
+ let toStringCallCount = 0;
+ const bodyArg = {
+ toString() {
+ toStringCallCount++;
+ return "return a;";
+ }
+ };
+
+ const f = new Function("a", bodyArg);
+ assertEquals(1, toStringCallCount);
+ assertEquals(5, f(5));
+})();
+
+(function TestSymbolToPrimitiveUsedForObjectArgument() {
+ let calls = 0;
+ const paramArg = {
+ [Symbol.toPrimitive](hint) {
+ calls++;
+ return "a";
+ }
+ };
+
+ const f = new Function(paramArg, "return a;");
+ assertEquals(1, calls);
+ assertEquals(9, f(9));
+})();
+
+// Rejection when the embedder callback disallows codegen
+(function TestCallbackRejectionThrowsEvalError() {
+ // %DisallowCodegenFromStrings installs a callback that always sets
+ // codegen_allowed = false. Only object (JSReceiver) arguments reach
+ // the callback; plain strings never do.
+ %DisallowCodegenFromStrings(true);
+ try {
+ assertThrows(() => {
+ new Function({ toString() { return "a"; } }, "return 1;");
+ }, EvalError);
+ } finally {
+ %DisallowCodegenFromStrings(false);
+ }
+})();
diff --git a/deps/v8/test/mjsunit/homomorphic-array-smi.js b/deps/v8/test/mjsunit/homomorphic-array-smi.js
index 46bc71374e2..7fec7dd13ed 100644
--- a/deps/v8/test/mjsunit/homomorphic-array-smi.js
+++ b/deps/v8/test/mjsunit/homomorphic-array-smi.js
@@ -8,19 +8,27 @@ function load_length(a) {
return a.length;
}
-const arrays = [];
-for (let i = 0; i < 11; i++) {
- const A = class extends Array {};
- arrays.push(new A());
-}
+class A1 extends Array {}
+class A2 extends Array {}
+class A3 extends Array {}
+class A4 extends Array {}
+class A5 extends Array {}
+
+let a1 = new A1();
+let a2 = new A2();
+let a3 = new A3();
+let a4 = new A4();
+let a5 = new A5();
%PrepareFunctionForOptimization(load_length);
-// Warm up with all 11 maps
+// Warm up with all 5 maps
for (let i = 0; i < 20; i++) {
- for (const a of arrays) {
- load_length(a);
- }
+ load_length(a1);
+ load_length(a2);
+ load_length(a3);
+ load_length(a4);
+ load_length(a5);
}
// Assert that the feedback is homomorphic
@@ -34,9 +42,11 @@ if (fb !== undefined) {
%OptimizeFunctionOnNextCall(load_length);
// Test return values for arrays
-for (const a of arrays) {
- assertEquals(0, load_length(a));
-}
+assertEquals(0, load_length(a1));
+assertEquals(0, load_length(a2));
+assertEquals(0, load_length(a3));
+assertEquals(0, load_length(a4));
+assertEquals(0, load_length(a5));
assertOptimized(load_length);
diff --git a/deps/v8/test/mjsunit/homomorphic-ic.js b/deps/v8/test/mjsunit/homomorphic-ic.js
index f904d091cf5..d3d80d4e10e 100644
--- a/deps/v8/test/mjsunit/homomorphic-ic.js
+++ b/deps/v8/test/mjsunit/homomorphic-ic.js
@@ -9,7 +9,7 @@ function load(o) {
}
let objects = [];
-for (let i = 0; i < 11; i++) {
+for (let i = 0; i < 10; i++) {
// Create functions with different maps but same shape
let F = new Function("x", "this.x = x;");
objects.push(new F(i));
@@ -17,7 +17,7 @@ for (let i = 0; i < 11; i++) {
// Warm up
%PrepareFunctionForOptimization(load);
-for (let i = 0; i < 11; i++) {
+for (let i = 0; i < 10; i++) {
load(objects[i]);
}
@@ -35,7 +35,7 @@ load(objects[0]);
assertOptimized(load);
// Check result
-for (let i = 0; i < 11; i++) {
+for (let i = 0; i < 10; i++) {
assertEquals(i, load(objects[i]));
assertOptimized(load);
}
diff --git a/deps/v8/test/mjsunit/lower_limits_mode/regress/regress-561323344.js b/deps/v8/test/mjsunit/lower_limits_mode/regress/regress-561323344.js
index 33f789ab9c4..8f25ad6841e 100644
--- a/deps/v8/test/mjsunit/lower_limits_mode/regress/regress-561323344.js
+++ b/deps/v8/test/mjsunit/lower_limits_mode/regress/regress-561323344.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --experimental-wasm-stringref
+// Flags: --allow-natives-syntax
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
diff --git a/deps/v8/test/mjsunit/maglev/add-number.js b/deps/v8/test/mjsunit/maglev/add-number.js
index 6ed3f32e717..db9f714bb08 100644
--- a/deps/v8/test/mjsunit/maglev/add-number.js
+++ b/deps/v8/test/mjsunit/maglev/add-number.js
@@ -14,15 +14,15 @@
%OptimizeMaglevOnNextCall(add);
assertEquals(4.2, add(2.1, 2.1));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
// We don't deopt if we use smis.
assertEquals(42, add(22, 20));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
// We deopt if not a number.
assertEquals("42", add("4", "2"));
- assertFalse(isMaglevved(add));
+ assertNotMaglevved(add);
})();
// Deopt in the second Float64Unbox when the first argument is a Smi.
@@ -36,11 +36,11 @@
%OptimizeMaglevOnNextCall(add);
assertEquals(4.2, add(2.1, 2.1));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
// We deopt if not a number.
assertEquals("42", add(4, "2"));
- assertFalse(isMaglevved(add));
+ assertNotMaglevved(add);
})();
// Deopt in the second Float64Unbox when the first argument is a double.
@@ -54,11 +54,11 @@
%OptimizeMaglevOnNextCall(add);
assertEquals(4.2, add(2.1, 2.1));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
// We deopt if not a number.
assertEquals("4.2!", add(4.2, "!"));
- assertFalse(isMaglevved(add));
+ assertNotMaglevved(add);
})();
// Emit FloatAdd through SmiAdd bytecode.
diff --git a/deps/v8/test/mjsunit/maglev/add-smi.js b/deps/v8/test/mjsunit/maglev/add-smi.js
index e2802c83241..282eb93ac19 100644
--- a/deps/v8/test/mjsunit/maglev/add-smi.js
+++ b/deps/v8/test/mjsunit/maglev/add-smi.js
@@ -15,10 +15,10 @@
%OptimizeMaglevOnNextCall(add);
assertEquals(3, add(1, 2));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
assertEquals(0x40000000, add(1, 0x3FFFFFFF));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
})();
// Checks when we deopt due to tagging.
@@ -32,9 +32,9 @@
%OptimizeMaglevOnNextCall(add);
assertEquals(3, add(1, 2));
- assertTrue(isMaglevved(add));
+ assertMaglevved(add);
// We should deopt here in Int32Add.
assertEquals(3.2, add(1.2, 2));
- assertFalse(isMaglevved(add));
+ assertNotMaglevved(add);
})();
diff --git a/deps/v8/test/mjsunit/maglev/alias-materialized-objects.js b/deps/v8/test/mjsunit/maglev/alias-materialized-objects.js
index 21336bc5c59..b52a8b79949 100644
--- a/deps/v8/test/mjsunit/maglev/alias-materialized-objects.js
+++ b/deps/v8/test/mjsunit/maglev/alias-materialized-objects.js
@@ -20,6 +20,6 @@ foo(0);
foo(0);
%OptimizeMaglevOnNextCall(foo);
foo(0);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertTrue(foo(1));
assertUnoptimized(foo);
diff --git a/deps/v8/test/mjsunit/maglev/array-iterator-next-polymorphic.js b/deps/v8/test/mjsunit/maglev/array-iterator-next-polymorphic.js
index 41075544db1..3542d74b8ca 100644
--- a/deps/v8/test/mjsunit/maglev/array-iterator-next-polymorphic.js
+++ b/deps/v8/test/mjsunit/maglev/array-iterator-next-polymorphic.js
@@ -24,11 +24,11 @@ test(array_double);
%OptimizeMaglevOnNextCall(test);
let res_smi = test(array_smi);
-assertTrue(isMaglevved(test));
+assertMaglevved(test);
assertEquals([1, 2], res_smi);
let res_double = test(array_double);
-assertTrue(isMaglevved(test));
+assertMaglevved(test);
assertEquals([1.1, 2.2], res_double);
// Now pass a different map (holey double) to trigger deopt if it was inlined
@@ -38,4 +38,4 @@ test(array_holey_double);
// We want to see if it deopted.
// If it deopted, isMaglevved should be false.
-assertFalse(isMaglevved(test));
+assertNotMaglevved(test);
diff --git a/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds-dict.js b/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds-dict.js
index 3ffa4580c4d..82e4beaa4b4 100644
--- a/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds-dict.js
+++ b/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds-dict.js
@@ -39,7 +39,7 @@ function plusOneInObject(x) {
const result2 = foo(array2);
assertTrue(HasHoleySmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testDictionaryElements2() {
@@ -62,7 +62,7 @@ function plusOneInObject(x) {
const result2 = foo(array2);
assertTrue(HasHoleyDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testDictionaryElements3() {
@@ -84,5 +84,5 @@ function plusOneInObject(x) {
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
diff --git a/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds.js b/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds.js
index ac325591db5..f0e392596c5 100644
--- a/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds.js
+++ b/deps/v8/test/mjsunit/maglev/array-prototype-map-elements-kinds.js
@@ -89,7 +89,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, 3];
const result2 = foo(array2);
assertTrue(HasPackedSmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testPackedSmiElements() {
@@ -107,7 +107,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, 3];
const result2 = foo(array2);
assertTrue(HasPackedSmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testHoleySmiElements() {
@@ -125,7 +125,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, , 3];
const result2 = foo(array2);
assertTrue(HasHoleySmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testPackedDoubleElements1() {
@@ -143,7 +143,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, 3.3];
const result2 = foo(array2);
assertTrue(HasPackedDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testPackedDoubleElements2() {
@@ -161,7 +161,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, 3];
const result2 = foo(array2);
assertTrue(HasPackedDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testHoleyDoubleElements1() {
@@ -179,7 +179,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, , 3.3];
const result2 = foo(array2);
assertTrue(HasHoleyDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testHoleyDoubleElements2() {
@@ -197,7 +197,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, , 3];
const result2 = foo(array2);
assertTrue(HasHoleyDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testPackedElements1() {
@@ -215,7 +215,7 @@ function resetTransitionFunctions() {
const array2 = [{a: 1}, {a: 2}, {a: 3}];
const result2 = foo(array2);
assertTrue(HasPackedObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testPackedElements2() {
@@ -233,7 +233,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, 3];
const result2 = foo(array2);
assertTrue(HasPackedObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testHoleyObjectElements1() {
@@ -251,7 +251,7 @@ function resetTransitionFunctions() {
const array2 = [{a: 1}, {a: 2}, , {a: 3}];
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testHoleyObjectElements2() {
@@ -269,7 +269,7 @@ function resetTransitionFunctions() {
const array2 = [1, 2, , 3];
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testFromObjectToPackedSmi() {
@@ -287,7 +287,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasPackedSmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testFromObjectToHoleySmi() {
@@ -305,7 +305,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasHoleySmiElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromPackedSmiToDoubleWhileMapping() {
@@ -326,7 +326,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasPackedDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromHoleySmiToDoubleWhileMapping() {
@@ -347,7 +347,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasHoleyDoubleElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromPackedSmiToObjectWhileMapping() {
@@ -368,7 +368,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasPackedObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromHoleySmiToObjectWhileMapping() {
@@ -389,7 +389,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromPackedSmiToDoubleToObjectWhileMapping() {
@@ -410,7 +410,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasPackedObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromHoleySmiToDoubleToObjectWhileMapping() {
@@ -431,7 +431,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromPackedSmiToObjectToDoubleWhileMapping() {
@@ -452,7 +452,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasPackedObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testTransitionFromHoleySmiToObjectToDoubleWhileMapping() {
@@ -473,7 +473,7 @@ function resetTransitionFunctions() {
const result2 = foo(array2);
assertTrue(HasHoleyObjectElements(result2));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
(function testMapperReducesLength() {
@@ -500,5 +500,5 @@ function resetTransitionFunctions() {
const result2 = foo(array);
assertTrue(HasHoleySmiElements(result2));
assertEquals(undefined, result2[2]);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
diff --git a/deps/v8/test/mjsunit/maglev/array-push-with-impossible-type.js b/deps/v8/test/mjsunit/maglev/array-push-with-impossible-type.js
index 79d7f446e30..bcb0c451289 100644
--- a/deps/v8/test/mjsunit/maglev/array-push-with-impossible-type.js
+++ b/deps/v8/test/mjsunit/maglev/array-push-with-impossible-type.js
@@ -20,7 +20,7 @@ const a2 = [1.2];
f(a2);
// Immediate deopt.
-assertFalse(isMaglevved(f));
+assertNotMaglevved(f);
assertEquals(3, a2.length);
assertTrue(%HasPackedElements(a2));
diff --git a/deps/v8/test/mjsunit/maglev/array-push-with-smi-object.js b/deps/v8/test/mjsunit/maglev/array-push-with-smi-object.js
index 760277cf4fb..bba62c82e6d 100644
--- a/deps/v8/test/mjsunit/maglev/array-push-with-smi-object.js
+++ b/deps/v8/test/mjsunit/maglev/array-push-with-smi-object.js
@@ -35,9 +35,9 @@ let smis = [1, 2, 3];
foo(smis, 11);
assertEquals(11, smis[3]);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Trying to store an object into a SMI array deopts.
foo(smis, {a: 2});
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
assertEquals(2, smis[4].a);
diff --git a/deps/v8/test/mjsunit/maglev/call-js-runtime.js b/deps/v8/test/mjsunit/maglev/call-js-runtime.js
index 972f464b293..a7a9872064c 100644
--- a/deps/v8/test/mjsunit/maglev/call-js-runtime.js
+++ b/deps/v8/test/mjsunit/maglev/call-js-runtime.js
@@ -18,4 +18,4 @@ assertEquals(2, foo([2]).bar);
%OptimizeMaglevOnNextCall(foo);
assertEquals(1, foo([1]).bar);
assertEquals(2, foo([2]).bar);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/call-runtime-for-pair.js b/deps/v8/test/mjsunit/maglev/call-runtime-for-pair.js
index 1367401142c..a663e4ffe0b 100644
--- a/deps/v8/test/mjsunit/maglev/call-runtime-for-pair.js
+++ b/deps/v8/test/mjsunit/maglev/call-runtime-for-pair.js
@@ -20,4 +20,4 @@ assertEquals(2, foo(2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(2, foo(2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js b/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js
index efc2bb023a2..6083e790789 100644
--- a/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js
+++ b/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js
@@ -25,7 +25,7 @@ assertEquals(-1, f(0, -1, true));
%OptimizeMaglevOnNextCall(f);
assertEquals(42, f(0, -1, false));
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
assertEquals(-1, f(0, -1, true));
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
diff --git a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono.js b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono.js
index bac07c40735..ab84688298d 100644
--- a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono.js
+++ b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono.js
@@ -28,13 +28,13 @@ const nonzero = new Vector(0.6); // Map2
magnitude(zero);
// The first call immediately deopts
-assertFalse(isMaglevved(magnitude));
+assertNotMaglevved(magnitude);
// But we learn and don't deopt any more.
%OptimizeMaglevOnNextCall(magnitude);
magnitude(zero);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
// Also passing other old objects won't deopt.
magnitude(anotherOldObject);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
diff --git a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono2.js b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono2.js
index 60f9fb6f6fd..2fd520ceb53 100644
--- a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono2.js
+++ b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-mono2.js
@@ -28,4 +28,4 @@ const nonzero = new Vector(0.6); // Map2
magnitude(nonzero);
// The first doesn't deopt if we pass a new object right away.
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
diff --git a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly.js b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly.js
index 897a6def603..2a21a5ffcb4 100644
--- a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly.js
+++ b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly.js
@@ -32,13 +32,13 @@ const nonzero = new Vector(0.6); // Map2
magnitude(zero);
// The first call immediately deopts
-assertFalse(isMaglevved(magnitude));
+assertNotMaglevved(magnitude);
// But we learn and don't deopt any more.
%OptimizeMaglevOnNextCall(magnitude);
magnitude(zero);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
// Also passing other old objects won't deopt.
magnitude(anotherOldObject);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
diff --git a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly2.js b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly2.js
index 85ee7adc6cf..970164c9693 100644
--- a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly2.js
+++ b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly2.js
@@ -32,4 +32,4 @@ const nonzero = new Vector(0.6); // Map2
magnitude(nonzero);
// The first call doesn't deopt if called with a new object.
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
diff --git a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly3.js b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly3.js
index 45c77510537..e61e4c21e73 100644
--- a/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly3.js
+++ b/deps/v8/test/mjsunit/maglev/checkmaps-with-migration-and-deopt-poly3.js
@@ -33,9 +33,9 @@ magnitude(unrelated);
%OptimizeMaglevOnNextCall(magnitude);
magnitude(newObject);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
// It should now migrate old objects.
magnitude(anotherOldObject);
-assertTrue(isMaglevved(magnitude));
+assertMaglevved(magnitude);
diff --git a/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js b/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js
index a1119434997..dfdcd99f710 100644
--- a/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js
+++ b/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js
@@ -73,7 +73,7 @@ for (const [fn, makeArg] of fns) {
%OptimizeMaglevOnNextCall(fn);
assertEquals(9, fn(makeArg()));
assertEquals(9, fn(makeArg()));
- assertTrue(isMaglevved(fn), fn.name);
+ assertMaglevved(fn, fn.name);
}
// A polymorphic iteration kind stays on the dynamic dispatch instead of
@@ -92,5 +92,5 @@ function step(it) {
step(m.entries());
step(m.keys());
step(m.values());
- assertTrue(isMaglevved(step));
+ assertMaglevved(step);
}
diff --git a/deps/v8/test/mjsunit/maglev/const-string-concat.js b/deps/v8/test/mjsunit/maglev/const-string-concat.js
index 76f0d6b5438..fa4878e5976 100644
--- a/deps/v8/test/mjsunit/maglev/const-string-concat.js
+++ b/deps/v8/test/mjsunit/maglev/const-string-concat.js
@@ -17,4 +17,4 @@ function foo2() {
assertEquals('foobar', foo2());
%OptimizeMaglevOnNextCall(foo2);
assertEquals('foobar', foo2());
-assertTrue(isMaglevved(foo2));
+assertMaglevved(foo2);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-detach.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-detach.js
index b006687b72f..6490998b21b 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-detach.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-detach.js
@@ -29,8 +29,8 @@ assertEquals(10, foo(10));
assertEquals(3, foo(3));
assertEquals(10, foo(10));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Detaching the buffer deopts.
%ArrayBufferDetach(ab);
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-oob.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-oob.js
index ac948e40d78..16aa31eb9fd 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-oob.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-deopt-oob.js
@@ -29,8 +29,8 @@ assertEquals(10, foo(10));
assertEquals(3, foo(3));
assertEquals(10, foo(10));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Going out of bounds deopts.
assertEquals(undefined, foo(1000));
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-double.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-double.js
index 1fd29253e30..295281e3111 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-double.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-double.js
@@ -34,4 +34,4 @@ function test() {
%NeverOptimizeFunction(test);
test();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-no-rab-gsab.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-no-rab-gsab.js
index a6f2d756f22..f69971a205b 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-no-rab-gsab.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-no-rab-gsab.js
@@ -30,16 +30,16 @@ assertEquals(10, foo(10));
assertEquals(3, foo(3));
assertEquals(10, foo(10));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// We don't optimize loading from the constant typed array, so we then also
// don't deopt if we read out of bounds, the array buffer is detached, etc.
assertEquals(undefined, foo(1000));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
ab.resize(50);
assertEquals(undefined, foo(30));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
%ArrayBufferDetach(ab);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-signed.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-signed.js
index 9aa76fcd4ff..581e9832363 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-signed.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-signed.js
@@ -34,4 +34,4 @@ function test() {
%NeverOptimizeFunction(test);
test();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-unsigned.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-unsigned.js
index 0010e0a1615..fc57b846235 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-load-unsigned.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-load-unsigned.js
@@ -34,4 +34,4 @@ function test() {
%NeverOptimizeFunction(test);
test();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-detach.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-detach.js
index 05aca4578af..958a618bed5 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-detach.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-detach.js
@@ -28,9 +28,9 @@ assertEquals(20, constTypedArray[10]);
foo(13, 14);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(14, constTypedArray[13]);
// Detaching the buffer deopts.
%ArrayBufferDetach(ab);
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-oob.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-oob.js
index d051e6fa5b5..bfa5a77a03a 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-oob.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-deopt-oob.js
@@ -28,9 +28,9 @@ assertEquals(20, constTypedArray[10]);
foo(13, 14);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(14, constTypedArray[13]);
// Going out of bounds deopts.
foo(1000, 0);
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-double.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-double.js
index f626f3089d7..2b02a95237f 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-double.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-double.js
@@ -36,7 +36,7 @@ function test() {
%NeverOptimizeFunction(test);
test();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
const source = new ArrayBuffer(8);
new BigUint64Array(source)[0] = 0xfff2800000000000n;
@@ -56,5 +56,5 @@ const expectedBits = targetBits[0];
%OptimizeMaglevOnNextCall(storeSignalingNaN);
storeSignalingNaN(signalingNaN);
-assertTrue(isMaglevved(storeSignalingNaN));
+assertMaglevved(storeSignalingNaN);
assertEquals(expectedBits, targetBits[0]);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-int.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-int.js
index e03f5673c36..c8e2d510659 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-int.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-int.js
@@ -36,4 +36,4 @@ function test() {
%NeverOptimizeFunction(test);
test();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-no-rab-gsab.js b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-no-rab-gsab.js
index a3bb38530ca..41554e267ca 100644
--- a/deps/v8/test/mjsunit/maglev/constant-typed-array-store-no-rab-gsab.js
+++ b/deps/v8/test/mjsunit/maglev/constant-typed-array-store-no-rab-gsab.js
@@ -29,17 +29,17 @@ assertEquals(20, constTypedArray[10]);
foo(13, 14);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(14, constTypedArray[13]);
// We don't optimize storing into the constant typed array, so we then also
// don't deopt if we store out of bounds, the array buffer is detached, etc.
foo(1000, 0);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
ab.resize(50);
foo(30, 0);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
%ArrayBufferDetach(ab);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/context-extension-mutability.js b/deps/v8/test/mjsunit/maglev/context-extension-mutability.js
new file mode 100644
index 00000000000..0f0db242960
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/context-extension-mutability.js
@@ -0,0 +1,78 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+// Flags: --optimize-on-next-call-optimizes-to-maglev
+
+globalThis.x = "global";
+
+// Test 1: Sloppy eval extending the outer context after `inner` has been
+// optimized with function context specialization. The extension slot must not
+// be constant-folded to `undefined`.
+(function TestExtensionMutatedBetweenCalls() {
+ function outer(cb) {
+ if (!cb) {
+ eval('var x = "init";');
+ return;
+ }
+ const inner = function () {
+ return x;
+ };
+ cb(inner, false);
+ eval('var x = "shadowed";');
+ cb(inner, true);
+ }
+
+ // Invalidate the EmptyContextExtension dependency on outer's ScopeInfo.
+ outer(null);
+
+ outer((inner, after_eval) => {
+ if (!after_eval) {
+ %PrepareFunctionForOptimization(inner);
+ assertEquals("global", inner());
+ %OptimizeFunctionOnNextCall(inner);
+ assertEquals("global", inner());
+ } else {
+ assertEquals("shadowed", inner());
+ }
+ });
+})();
+
+// Test 2: Sloppy eval extending the outer context in the middle of an
+// optimized function (via generator resume) between two dynamic global
+// lookups. The extension slot load before the call must not be cached as an
+// immutable constant across the call.
+(function TestExtensionMutatedDuringCall() {
+ let gen;
+ function advance(resume) {
+ if (resume) gen.next();
+ }
+ %NeverOptimizeFunction(advance);
+
+ function* outer(init_eval) {
+ if (init_eval) {
+ eval('var x = "init";');
+ return;
+ }
+ const inner = function (resume) {
+ const before = x;
+ advance(resume);
+ const after = x;
+ return [before, after];
+ };
+ yield inner;
+ eval('var x = "shadowed_mid_call";');
+ }
+
+ outer(true).next();
+
+ gen = outer(false);
+ const inner = gen.next().value;
+ %PrepareFunctionForOptimization(inner);
+ assertEquals(["global", "global"], inner(false));
+ %OptimizeFunctionOnNextCall(inner);
+ assertEquals(["global", "global"], inner(false));
+
+ assertEquals(["global", "shadowed_mid_call"], inner(true));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/context-inverted-generator3.js b/deps/v8/test/mjsunit/maglev/context-inverted-generator3.js
new file mode 100644
index 00000000000..3a91ef8ec3c
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/context-inverted-generator3.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+function* f() {
+ yield function g() {
+ try { test } catch (e) { gen.next(); return test }
+ }
+ const test = 10;
+}
+
+var gen = f();
+var g = gen.next().value;
+%PrepareFunctionForOptimization(g);
+assertEquals(10, g());
+
+gen = f();
+g = gen.next().value;
+assertEquals(10, g());
+
+gen = f();
+g = gen.next().value;
+assertEquals(10, g());
+
+gen = f();
+g = gen.next().value;
+%OptimizeMaglevOnNextCall(g);
+assertEquals(10, g());
diff --git a/deps/v8/test/mjsunit/maglev/dataview-getbytelength-not-dataview.js b/deps/v8/test/mjsunit/maglev/dataview-getbytelength-not-dataview.js
index b11b0f5b467..e3df8359dde 100644
--- a/deps/v8/test/mjsunit/maglev/dataview-getbytelength-not-dataview.js
+++ b/deps/v8/test/mjsunit/maglev/dataview-getbytelength-not-dataview.js
@@ -26,4 +26,4 @@ assertEquals('exception', foo(notDv));
assertEquals(100, foo(dv));
assertEquals('exception', foo(notDv));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/dataview-getbytelength-undefined.js b/deps/v8/test/mjsunit/maglev/dataview-getbytelength-undefined.js
index 7f6d3db98c4..939c8086e1f 100644
--- a/deps/v8/test/mjsunit/maglev/dataview-getbytelength-undefined.js
+++ b/deps/v8/test/mjsunit/maglev/dataview-getbytelength-undefined.js
@@ -23,4 +23,4 @@ assertEquals('exception', foo());
assertEquals(100, foo(dv));
assertEquals('exception', foo());
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/dataview-getbytelength.js b/deps/v8/test/mjsunit/maglev/dataview-getbytelength.js
index 7942d2b061c..597f2420e37 100644
--- a/deps/v8/test/mjsunit/maglev/dataview-getbytelength.js
+++ b/deps/v8/test/mjsunit/maglev/dataview-getbytelength.js
@@ -17,4 +17,4 @@ assertEquals(100, foo(dv));
%OptimizeMaglevOnNextCall(foo);
assertEquals(100, foo(dv));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/define-const-data-field-class-field.js b/deps/v8/test/mjsunit/maglev/define-const-data-field-class-field.js
new file mode 100644
index 00000000000..59c799cf2c6
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/define-const-data-field-class-field.js
@@ -0,0 +1,145 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+
+// A DefineNamedOwnProperty into a const field may only keep the field const
+// when the field still holds the uninitialized value, i.e. when the define is
+// the initializing store of an object literal. A define into an already
+// initialized const field must generalize the field to mutable.
+
+// Class field initializer, run on an already initialized object via return
+// override. The define site is megamorphic and has never seen an H; Maglev
+// knows the receiver's map from the preceding load. The define must generalize
+// the field.
+
+(function TestDefineIntoInitializedConstField() {
+ function H(v) { this.myProp = v; }
+ const first = {};
+ const second = {};
+ const holder = new H(first);
+ const other = new H(second);
+
+ class Base { constructor(o) { return o; } }
+ class D extends Base { myProp = second; }
+
+ // Make the define site megamorphic without ever seeing an H.
+ for (let i = 0; i < 30; i++) {
+ const o = {};
+ o["p" + i] = i;
+ new D(o);
+ }
+
+ function define(o, constructD) {
+ const t = o.myProp; // Known maps for o: {H, literal}.
+ if (constructD) new D(o);
+ return t;
+ }
+ %PrepareFunctionForOptimization(define);
+ // One call with an H to get its map into the load feedback, without
+ // constructing D on it (that would generalize H.myProp in the runtime).
+ define(other, false);
+ // The other calls construct D, so that its call frequency stays high enough
+ // for Maglev to inline it.
+ for (let i = 0; i < 30; i++) define({myProp: second}, true);
+ %OptimizeMaglevOnNextCall(define);
+ define({myProp: second}, true);
+ assertMaglevved(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H.
+ assertSame(first, define(holder, true));
+ assertSame(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
+
+// Same, but the const field has Smi representation. The representation is
+// determined by the first store in H; there is no runtime function to assert
+// it, so the test relies on 1 giving a Smi field.
+(function TestDefineIntoInitializedConstSmiField() {
+ function H(v) { this.myProp = v; }
+ const first = 1;
+ const second = 2;
+ const holder = new H(first);
+ const other = new H(second);
+
+ class Base { constructor(o) { return o; } }
+ class D extends Base { myProp = second; }
+
+ // Make the define site megamorphic without ever seeing an H.
+ for (let i = 0; i < 30; i++) {
+ const o = {};
+ o["p" + i] = i;
+ new D(o);
+ }
+
+ function define(o, constructD) {
+ const t = o.myProp; // Known maps for o: {H, literal}.
+ if (constructD) new D(o);
+ return t;
+ }
+ %PrepareFunctionForOptimization(define);
+ // One call with an H to get its map into the load feedback, without
+ // constructing D on it (that would generalize H.myProp in the runtime).
+ define(other, false);
+ // The other calls construct D, so that its call frequency stays high enough
+ // for Maglev to inline it.
+ for (let i = 0; i < 30; i++) define({myProp: second}, true);
+ %OptimizeMaglevOnNextCall(define);
+ define({myProp: second}, true);
+ assertMaglevved(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H.
+ assertSame(first, define(holder, true));
+ assertSame(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
+
+// Same, but the const field has Double representation.
+(function TestDefineIntoInitializedConstDoubleField() {
+ function H(v) { this.myProp = v; }
+ const first = 1.5;
+ const second = 2.5;
+ const holder = new H(first);
+ const other = new H(second);
+
+ class Base { constructor(o) { return o; } }
+ class D extends Base { myProp = second; }
+
+ // Make the define site megamorphic without ever seeing an H.
+ for (let i = 0; i < 30; i++) {
+ const o = {};
+ o["p" + i] = i;
+ new D(o);
+ }
+
+ function define(o, constructD) {
+ const t = o.myProp; // Known maps for o: {H, literal}.
+ if (constructD) new D(o);
+ return t;
+ }
+ %PrepareFunctionForOptimization(define);
+ // One call with an H to get its map into the load feedback, without
+ // constructing D on it (that would generalize H.myProp in the runtime).
+ define(other, false);
+ // The other calls construct D, so that its call frequency stays high enough
+ // for Maglev to inline it.
+ for (let i = 0; i < 30; i++) define({myProp: second}, true);
+ %OptimizeMaglevOnNextCall(define);
+ define({myProp: second}, true);
+ assertMaglevved(define);
+
+ // Assert the good state before we begin the shenanigans.
+ assertTrue(%HasOwnConstDataProperty(holder, "myProp"));
+
+ // This call should invalidate the constness of 'myProp' in H.
+ assertEquals(first, define(holder, true));
+ assertEquals(second, holder.myProp);
+ assertFalse(%HasOwnConstDataProperty(holder, "myProp"));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/define-const-data-field-object-literal.js b/deps/v8/test/mjsunit/maglev/define-const-data-field-object-literal.js
new file mode 100644
index 00000000000..df1ca3a7dec
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/define-const-data-field-object-literal.js
@@ -0,0 +1,68 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+
+// A DefineNamedOwnProperty into a const field may only keep the field const
+// when the field still holds the uninitialized value, i.e. when the define is
+// the initializing store of an object literal. In these tests the define is
+// the initializing store, so Maglev code must not deoptimize and the field
+// must stay const.
+
+(function TestObjectLiteralStaysOptimized() {
+ function make(x) {
+ return {a: x};
+ }
+
+ %PrepareFunctionForOptimization(make);
+ // The literal needs two executions before its feedback has a boilerplate.
+ make({});
+ assertTrue(%HasOwnConstDataProperty(make({}), "a"));
+
+ %OptimizeMaglevOnNextCall(make);
+ const marker = {};
+ const o = make(marker);
+ assertSame(marker, o.a);
+ assertMaglevved(make);
+ assertTrue(%HasOwnConstDataProperty(o, "a"));
+})();
+
+// Same, but the const field has Smi representation. The representation is
+// determined by the first store; there is no runtime function to assert it,
+// so the test relies on 1 giving a Smi field. The property name differs from
+// the one above because object literals of the same shape share their map
+// transitions, and the field of the transition above already has HeapObject
+// representation.
+(function TestObjectLiteralSmiStaysOptimized() {
+ function make(x) {
+ return {b: x};
+ }
+
+ %PrepareFunctionForOptimization(make);
+ make(1);
+ assertTrue(%HasOwnConstDataProperty(make(2), "b"));
+
+ %OptimizeMaglevOnNextCall(make);
+ const o = make(3);
+ assertEquals(3, o.b);
+ assertMaglevved(make);
+ assertTrue(%HasOwnConstDataProperty(o, "b"));
+})();
+
+// Same, but the const field has Double representation.
+(function TestObjectLiteralDoubleStaysOptimized() {
+ function make(x) {
+ return {c: x};
+ }
+
+ %PrepareFunctionForOptimization(make);
+ make(1.5);
+ assertTrue(%HasOwnConstDataProperty(make(2.5), "c"));
+
+ %OptimizeMaglevOnNextCall(make);
+ const o = make(3.5);
+ assertEquals(3.5, o.c);
+ assertMaglevved(make);
+ assertTrue(%HasOwnConstDataProperty(o, "c"));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/define-const-data-field-spread-literal.js b/deps/v8/test/mjsunit/maglev/define-const-data-field-spread-literal.js
new file mode 100644
index 00000000000..1b10b3548ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/define-const-data-field-spread-literal.js
@@ -0,0 +1,81 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+
+// A DefineNamedOwnProperty into a const field may only keep the field const
+// when the field still holds the uninitialized value, i.e. when the define is
+// the initializing store of an object literal. An object literal with a spread
+// clones the source object and then defines the remaining properties into the
+// clone, so the define may hit an already initialized const field copied from
+// the source. It must then generalize the field to mutable.
+//
+// Note that Maglev does not know the map of the cloned object, so the define
+// is compiled from its own feedback, which the runtime only produces after it
+// has already generalized the field. These tests therefore document the
+// expected behavior; they do not exercise the uninitialized check in the
+// optimized code.
+
+(function TestSpreadDefineIntoInitializedConstField() {
+ const first = {};
+ const second = {};
+ function make(src) {
+ return {...src, a: second};
+ }
+
+ const src = {a: first};
+ assertTrue(%HasOwnConstDataProperty(src, "a"));
+
+ %PrepareFunctionForOptimization(make);
+ make(src);
+ make(src);
+ %OptimizeMaglevOnNextCall(make);
+ const o = make(src);
+ assertSame(second, o.a);
+ assertMaglevved(make);
+ assertFalse(%HasOwnConstDataProperty(o, "a"));
+ assertSame(first, src.a);
+})();
+
+// Same, but the const field has Smi representation. The representation is
+// determined by the first store; there is no runtime function to assert it,
+// so the test relies on 1 giving a Smi field.
+(function TestSpreadDefineIntoInitializedConstSmiField() {
+ function make(src) {
+ return {...src, b: 2};
+ }
+
+ const src = {b: 1};
+ assertTrue(%HasOwnConstDataProperty(src, "b"));
+
+ %PrepareFunctionForOptimization(make);
+ make(src);
+ make(src);
+ %OptimizeMaglevOnNextCall(make);
+ const o = make(src);
+ assertEquals(2, o.b);
+ assertMaglevved(make);
+ assertFalse(%HasOwnConstDataProperty(o, "b"));
+ assertEquals(1, src.b);
+})();
+
+// Same, but the const field has Double representation.
+(function TestSpreadDefineIntoInitializedConstDoubleField() {
+ function make(src) {
+ return {...src, c: 2.5};
+ }
+
+ const src = {c: 1.5};
+ assertTrue(%HasOwnConstDataProperty(src, "c"));
+
+ %PrepareFunctionForOptimization(make);
+ make(src);
+ make(src);
+ %OptimizeMaglevOnNextCall(make);
+ const o = make(src);
+ assertEquals(2.5, o.c);
+ assertMaglevved(make);
+ assertFalse(%HasOwnConstDataProperty(o, "c"));
+ assertEquals(1.5, src.c);
+})();
diff --git a/deps/v8/test/mjsunit/maglev/destructuring-assignment-with-exclude-properties.js b/deps/v8/test/mjsunit/maglev/destructuring-assignment-with-exclude-properties.js
index 23b5c2490cc..456d32f7f02 100644
--- a/deps/v8/test/mjsunit/maglev/destructuring-assignment-with-exclude-properties.js
+++ b/deps/v8/test/mjsunit/maglev/destructuring-assignment-with-exclude-properties.js
@@ -14,4 +14,4 @@ assertEquals({c:1, d:1}, foo());
assertEquals({c:1, d:1}, foo());
%OptimizeMaglevOnNextCall(foo);
assertEquals({c:1, d:1}, foo());
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/dict-load.js b/deps/v8/test/mjsunit/maglev/dict-load.js
index 1ae55205d45..a01077919ba 100644
--- a/deps/v8/test/mjsunit/maglev/dict-load.js
+++ b/deps/v8/test/mjsunit/maglev/dict-load.js
@@ -30,7 +30,7 @@ assertEquals("safe_value", getTargetField(dictObj));
// Trigger Maglev optimization.
%OptimizeMaglevOnNextCall(getTargetField);
assertEquals("safe_value", getTargetField(dictObj));
-assertTrue(isMaglevved(getTargetField));
+assertMaglevved(getTargetField);
// Test the fallback path: Value change.
dictObj.target_property = "updated_value";
diff --git a/deps/v8/test/mjsunit/maglev/dont-forget-holes.js b/deps/v8/test/mjsunit/maglev/dont-forget-holes.js
index 3ea7d064e65..11cfc633f1f 100644
--- a/deps/v8/test/mjsunit/maglev/dont-forget-holes.js
+++ b/deps/v8/test/mjsunit/maglev/dont-forget-holes.js
@@ -22,4 +22,4 @@ foo([0.5, 1.0, 1.5]);
foo([0.5, , 1.5]);
// No deopts since we generated code to handle the hole.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/dont-forget-oob.js b/deps/v8/test/mjsunit/maglev/dont-forget-oob.js
index d3707db693a..30e159ef59c 100644
--- a/deps/v8/test/mjsunit/maglev/dont-forget-oob.js
+++ b/deps/v8/test/mjsunit/maglev/dont-forget-oob.js
@@ -22,4 +22,4 @@ foo([1, 2, 3]);
foo([0.5]);
// No deopts since we generated code to handle the OOB.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/equals-number-boolean.js b/deps/v8/test/mjsunit/maglev/equals-number-boolean.js
index 39bd2e8efae..3b15c0118b7 100644
--- a/deps/v8/test/mjsunit/maglev/equals-number-boolean.js
+++ b/deps/v8/test/mjsunit/maglev/equals-number-boolean.js
@@ -44,9 +44,9 @@ assertEquals(0, equals(false, true));
assertEquals(0, equals(true, false));
assertEquals(0, equals(3, 4));
-assertTrue(isMaglevved(equals));
+assertMaglevved(equals);
// Passing a non-boolean oddball deopts.
assertEquals(0, equals(undefined, true));
-assertFalse(isMaglevved(equals));
+assertNotMaglevved(equals);
diff --git a/deps/v8/test/mjsunit/maglev/extras-cped.js b/deps/v8/test/mjsunit/maglev/extras-cped.js
index 7d63c871d88..0c823a933c0 100644
--- a/deps/v8/test/mjsunit/maglev/extras-cped.js
+++ b/deps/v8/test/mjsunit/maglev/extras-cped.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --maglev
const {
getExtrasBindingObject,
@@ -36,4 +36,4 @@ runTestOpt(5);
runTestOpt(5.5);
runTestOpt({});
-assertTrue(isMaglevved(testOpt));
+assertMaglevved(testOpt);
diff --git a/deps/v8/test/mjsunit/maglev/float64-conversions.js b/deps/v8/test/mjsunit/maglev/float64-conversions.js
index 52466085703..44a51347a54 100644
--- a/deps/v8/test/mjsunit/maglev/float64-conversions.js
+++ b/deps/v8/test/mjsunit/maglev/float64-conversions.js
@@ -24,7 +24,7 @@ const typed = new Float64Array([1.5, 2.5]);
assertEquals(Math.sqrt(1.5), f(packed, 0));
%OptimizeMaglevOnNextCall(f);
assertEquals(Math.sqrt(2.5), f(packed, 1));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// An Int32, and a Uint32.
@@ -44,8 +44,8 @@ const typed = new Float64Array([1.5, 2.5]);
assertEquals(3, f(9));
assertEquals(3, g(9));
assertEquals(Math.sqrt(2 ** 32 - 1), g(-1));
- assertTrue(isMaglevved(f));
- assertTrue(isMaglevved(g));
+ assertMaglevved(f);
+ assertMaglevved(g);
})();
// A tagged value known to be a Smi, which is untagged and converted from its
@@ -57,7 +57,7 @@ const typed = new Float64Array([1.5, 2.5]);
assertEquals(1, f(smis, 0));
%OptimizeMaglevOnNextCall(f);
assertEquals(Math.sqrt(2), f(smis, 1));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// A tagged value that is a number but not a Smi.
@@ -108,7 +108,7 @@ const typed = new Float64Array([1.5, 2.5]);
%OptimizeMaglevOnNextCall(f);
assertEquals(4.5, f(holey, 2));
assertEquals(NaN, f(holey, 1));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// A HoleyFloat64 stored into a packed double array, where the hole is not a
@@ -142,7 +142,7 @@ const typed = new Float64Array([1.5, 2.5]);
%OptimizeMaglevOnNextCall(f);
assertEquals(8.75, f(6.25, false));
assertEquals(9.75, f(6.25, true));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// An IntPtr, which is what a typed array length is.
@@ -178,7 +178,7 @@ const typed = new Float64Array([1.5, 2.5]);
assertEquals(5.25, f({x: 2.25}));
%OptimizeMaglevOnNextCall(f);
assertEquals(11.25, f({x: 6.25}));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// ----------------------------------------------------------- to HoleyFloat64
@@ -208,7 +208,7 @@ function store(v, i) {
f(holey, 1, h, 0); // the hole reads as undefined and stays undefined
assertTrue(0 in h);
assertEquals(undefined, h[0]);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// A constant, including the undefined one.
@@ -347,5 +347,5 @@ function store(v, i) {
f({x: 6.25}, h, 0, 2);
assertEquals(6.25, h[0]);
assertEquals(6.25, h[2]);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
diff --git a/deps/v8/test/mjsunit/maglev/get-template-object.js b/deps/v8/test/mjsunit/maglev/get-template-object.js
index 58347d8a17b..7b0ce46654f 100644
--- a/deps/v8/test/mjsunit/maglev/get-template-object.js
+++ b/deps/v8/test/mjsunit/maglev/get-template-object.js
@@ -17,4 +17,4 @@ assertEquals(["123", "", 2], foo(2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(["123", "", 1], foo(1));
assertEquals(["123", "", 2], foo(2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js b/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js
index 3732ffe9860..e63c1a30c6f 100644
--- a/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js
+++ b/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js
@@ -109,7 +109,7 @@
assertTrue(isNaN(f(a, 1, 2, true))); // undefined + 1 = NaN
%OptimizeMaglevOnNextCall(f);
assertEquals(2.5, f(a, 0, 2, true));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
assertTrue(isNaN(f(a, 1, 2, true)));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
diff --git a/deps/v8/test/mjsunit/maglev/holey-float64-exception-phi.js b/deps/v8/test/mjsunit/maglev/holey-float64-exception-phi.js
index ca1321e086a..58e8133f0c9 100644
--- a/deps/v8/test/mjsunit/maglev/holey-float64-exception-phi.js
+++ b/deps/v8/test/mjsunit/maglev/holey-float64-exception-phi.js
@@ -33,4 +33,4 @@ assertEquals(42, foo(1, false));
assertEquals(2.5, foo(1, true));
assertEquals(42, foo(2, false));
assertEquals(undefined, foo(2, true));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/inline-fulfill-promise.js b/deps/v8/test/mjsunit/maglev/inline-fulfill-promise.js
index ed4b8a5822b..84cc70db949 100644
--- a/deps/v8/test/mjsunit/maglev/inline-fulfill-promise.js
+++ b/deps/v8/test/mjsunit/maglev/inline-fulfill-promise.js
@@ -11,7 +11,7 @@ function check(fn, expected) {
let r1 = fn();
%OptimizeMaglevOnNextCall(fn);
let r2 = fn();
- assertTrue(isMaglevved(fn));
+ assertMaglevved(fn);
return Promise.all([r0, r1, r2]).then(([v0, v1, v2]) => {
assertEquals(expected, v0);
assertEquals(expected, v1);
@@ -48,7 +48,7 @@ function check(fn, expected) {
let observed;
await ret_smi_2().then(v => { observed = v; });
assertEquals(99, observed);
- assertTrue(isMaglevved(ret_smi_2));
+ assertMaglevved(ret_smi_2);
// Non-primitive (Proxy) return: must NOT take the inlined path, because
// JSResolvePromise's "then" check is required. The Proxy below has no
@@ -59,7 +59,7 @@ function check(fn, expected) {
assertEquals(proxy, await ret_proxy(proxy));
%OptimizeMaglevOnNextCall(ret_proxy);
assertEquals(proxy, await ret_proxy(proxy));
- assertTrue(isMaglevved(ret_proxy));
+ assertMaglevved(ret_proxy);
// With an actual await, the async function object escapes through
// AsyncFunctionAwait, so the inlining must not fire. Just check correctness.
diff --git a/deps/v8/test/mjsunit/maglev/inner-function.js b/deps/v8/test/mjsunit/maglev/inner-function.js
index a9b4338dde0..dad8f2fd1f0 100644
--- a/deps/v8/test/mjsunit/maglev/inner-function.js
+++ b/deps/v8/test/mjsunit/maglev/inner-function.js
@@ -17,4 +17,4 @@ assertEquals(2, foo(2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(2, foo(2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/int32-branch.js b/deps/v8/test/mjsunit/maglev/int32-branch.js
index 9f74a5fb1d5..2aeaf850137 100644
--- a/deps/v8/test/mjsunit/maglev/int32-branch.js
+++ b/deps/v8/test/mjsunit/maglev/int32-branch.js
@@ -17,7 +17,7 @@ assertEquals(24, foo(6,2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(42, foo(1,2));
assertEquals(24, foo(6,2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(42, foo(1.1, 2.2));
assertEquals(24, foo(6.6, 2.2));
assertUnoptimized(foo);
@@ -36,7 +36,7 @@ assertEquals(24, bar(6,2));
%OptimizeMaglevOnNextCall(bar);
assertEquals(42, bar(1,2));
assertEquals(24, bar(6,2));
-assertTrue(isMaglevved(bar));
+assertMaglevved(bar);
assertEquals(42, bar(1.1, 2.2));
assertEquals(24, bar(6.6, 2.2));
assertUnoptimized(bar);
diff --git a/deps/v8/test/mjsunit/maglev/int32-mul-truncation.js b/deps/v8/test/mjsunit/maglev/int32-mul-truncation.js
index eb926ab3f74..8631529e7b3 100644
--- a/deps/v8/test/mjsunit/maglev/int32-mul-truncation.js
+++ b/deps/v8/test/mjsunit/maglev/int32-mul-truncation.js
@@ -22,7 +22,7 @@ mul_masked(268435455, 12345);
mul_masked(1000, 2000);
%OptimizeMaglevOnNextCall(mul_masked);
assertEquals(0, mul_masked(-268435455, 0));
-assertTrue(isMaglevved(mul_masked));
+assertMaglevved(mul_masked);
// The product feeds a truncatable add, so the multiplication still folds.
function mul_through_add(x, e, y, f) {
@@ -35,7 +35,7 @@ mul_through_add(268435455, 12345, 268435455, 12345);
mul_through_add(1000, 2000, 3000, 4000);
%OptimizeMaglevOnNextCall(mul_through_add);
assertEquals(199, mul_through_add(-268435455, 0, 268435455, 12345));
-assertTrue(isMaglevved(mul_through_add));
+assertMaglevved(mul_through_add);
// The product feeds a truncatable subtract.
function mul_through_sub(x, e, y, f) {
@@ -48,7 +48,7 @@ mul_through_sub(268435455, 12345, 268435455, 12345);
mul_through_sub(1000, 2000, 3000, 4000);
%OptimizeMaglevOnNextCall(mul_through_sub);
assertEquals(199, mul_through_sub(-268435455, 0, 268435455, 12345));
-assertTrue(isMaglevved(mul_through_sub));
+assertMaglevved(mul_through_sub);
// The fold fires inside a loop.
function mul_in_loop(n, x, e) {
@@ -64,7 +64,7 @@ mul_in_loop(5, 268435455, 12345);
mul_in_loop(5, 1000, 2000);
%OptimizeMaglevOnNextCall(mul_in_loop);
assertEquals(0, mul_in_loop(5, -268435455, 0));
-assertTrue(isMaglevved(mul_in_loop));
+assertMaglevved(mul_in_loop);
// The product is observed as a value (not truncated), so the minus-zero check
// must be kept: -0 stays -0 and +0 stays +0.
@@ -125,4 +125,4 @@ mul_above_int32(100, 200);
%OptimizeMaglevOnNextCall(mul_above_int32);
assertEquals(((0x3ffff * 0x3ffff) & 0x3fffffff),
mul_above_int32(0x3ffff, 0x3ffff));
-assertTrue(isMaglevved(mul_above_int32));
+assertMaglevved(mul_above_int32);
diff --git a/deps/v8/test/mjsunit/maglev/keyed-access-thin-constant-key.js b/deps/v8/test/mjsunit/maglev/keyed-access-thin-constant-key.js
index 9ff62204f95..ec2bc343f5c 100644
--- a/deps/v8/test/mjsunit/maglev/keyed-access-thin-constant-key.js
+++ b/deps/v8/test/mjsunit/maglev/keyed-access-thin-constant-key.js
@@ -24,7 +24,7 @@ acc.set(o, 1);
acc.set(o, 2);
%OptimizeMaglevOnNextCall(acc.set);
acc.set(o, 3);
-assertTrue(isMaglevved(acc.set));
+assertMaglevved(acc.set);
assertEquals(3, o[key]);
%PrepareFunctionForOptimization(acc.get);
@@ -32,4 +32,4 @@ assertEquals(3, acc.get(o));
assertEquals(3, acc.get(o));
%OptimizeMaglevOnNextCall(acc.get);
assertEquals(3, acc.get(o));
-assertTrue(isMaglevved(acc.get));
+assertMaglevved(acc.get);
diff --git a/deps/v8/test/mjsunit/maglev/large-typedarray-oob.js b/deps/v8/test/mjsunit/maglev/large-typedarray-oob.js
index 7beac9ededc..270f513c920 100644
--- a/deps/v8/test/mjsunit/maglev/large-typedarray-oob.js
+++ b/deps/v8/test/mjsunit/maglev/large-typedarray-oob.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Flags: --allow-natives-syntax --turbofan
+// Flags: --allow-natives-syntax --turbofan --mock-arraybuffer-allocator
function foo(array1, array2) {
let len = array1.length;
diff --git a/deps/v8/test/mjsunit/maglev/lazy-deopt-with-onstack-activation.js b/deps/v8/test/mjsunit/maglev/lazy-deopt-with-onstack-activation.js
index cd889181f20..19c0fe6a212 100644
--- a/deps/v8/test/mjsunit/maglev/lazy-deopt-with-onstack-activation.js
+++ b/deps/v8/test/mjsunit/maglev/lazy-deopt-with-onstack-activation.js
@@ -25,10 +25,10 @@ assertEquals(31, f());
%OptimizeMaglevOnNextCall(f);
assertEquals(31, f());
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
// Trigger a lazy deopt on the next g() call.
do_change = true;
assertEquals(42, f());
-assertFalse(isMaglevved(f));
+assertNotMaglevved(f);
assertUnoptimized(f);
diff --git a/deps/v8/test/mjsunit/maglev/lazy-deopt-without-onstack-activation.js b/deps/v8/test/mjsunit/maglev/lazy-deopt-without-onstack-activation.js
index 516759b43d5..efe45b3336d 100644
--- a/deps/v8/test/mjsunit/maglev/lazy-deopt-without-onstack-activation.js
+++ b/deps/v8/test/mjsunit/maglev/lazy-deopt-without-onstack-activation.js
@@ -15,10 +15,10 @@ assertEquals(1, f());
%OptimizeMaglevOnNextCall(f);
assertEquals(1, f());
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
// Trigger a lazy deopt now, so that f() deopts on its next call.
x = 2;
-assertFalse(isMaglevved(f));
+assertNotMaglevved(f);
assertUnoptimized(f);
assertEquals(2, f());
diff --git a/deps/v8/test/mjsunit/maglev/lda-global-inside-typeof.js b/deps/v8/test/mjsunit/maglev/lda-global-inside-typeof.js
index aea17381fd8..9919103326b 100644
--- a/deps/v8/test/mjsunit/maglev/lda-global-inside-typeof.js
+++ b/deps/v8/test/mjsunit/maglev/lda-global-inside-typeof.js
@@ -15,9 +15,9 @@ assertEquals("number", foo());
%OptimizeMaglevOnNextCall(foo);
assertEquals("number", foo());
assertEquals("number", foo());
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// We should deopt here.
b = 2
-assertFalse(isMaglevved(foo))
+assertNotMaglevved(foo)
assertEquals("number", foo());
diff --git a/deps/v8/test/mjsunit/maglev/lda-global.js b/deps/v8/test/mjsunit/maglev/lda-global.js
index 524b1cfa35a..6998a739d04 100644
--- a/deps/v8/test/mjsunit/maglev/lda-global.js
+++ b/deps/v8/test/mjsunit/maglev/lda-global.js
@@ -15,9 +15,9 @@ assertEquals(3, foo(2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(4, foo(3));
assertEquals(5, foo(4));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// We should deopt here.
b = 2
-assertFalse(isMaglevved(foo))
+assertNotMaglevved(foo)
assertEquals(7, foo(5));
diff --git a/deps/v8/test/mjsunit/maglev/lda-module-variable.mjs b/deps/v8/test/mjsunit/maglev/lda-module-variable.mjs
index 2f9e0f8d0ab..164929bf2eb 100644
--- a/deps/v8/test/mjsunit/maglev/lda-module-variable.mjs
+++ b/deps/v8/test/mjsunit/maglev/lda-module-variable.mjs
@@ -17,7 +17,7 @@ assertEquals(3, bar(2));
%OptimizeMaglevOnNextCall(bar);
assertEquals(2, bar(1));
assertEquals(3, bar(2));
-assertTrue(isMaglevved(bar));
+assertMaglevved(bar);
// Test LdaModuleVariable with exports.
export let x = 1;
@@ -29,5 +29,5 @@ assertEquals(3, foo(2));
%OptimizeMaglevOnNextCall(foo);
assertEquals(2, foo(1));
assertEquals(3, foo(2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/literals.js b/deps/v8/test/mjsunit/maglev/literals.js
index 518c8932e3a..03b26a9cde1 100644
--- a/deps/v8/test/mjsunit/maglev/literals.js
+++ b/deps/v8/test/mjsunit/maglev/literals.js
@@ -15,7 +15,7 @@
%OptimizeMaglevOnNextCall(f);
assertEquals(0, f().length);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// Calls builtin create shallow object.
@@ -30,7 +30,7 @@
%OptimizeMaglevOnNextCall(f);
assertEquals(42, f().a);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
// Calls runtime create literal object.
@@ -45,5 +45,5 @@
%OptimizeMaglevOnNextCall(f);
assertEquals(42, f().out.in);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
})();
diff --git a/deps/v8/test/mjsunit/maglev/load-named.js b/deps/v8/test/mjsunit/maglev/load-named.js
index 968d07cbaf1..14f8bf00f58 100644
--- a/deps/v8/test/mjsunit/maglev/load-named.js
+++ b/deps/v8/test/mjsunit/maglev/load-named.js
@@ -15,11 +15,11 @@
%OptimizeMaglevOnNextCall(load);
assertEquals(42, load({smi:42}));
- assertTrue(isMaglevved(load));
+ assertMaglevved(load);
// We should deopt here.
assertEquals(42, load({y:0, smi:42}));
- assertFalse(isMaglevved(load));
+ assertNotMaglevved(load);
})();
// Checks simple monomorphic load of a Double field works
@@ -33,11 +33,11 @@
%OptimizeMaglevOnNextCall(load);
assertEquals(42.5, load({float64:42.5}));
- assertTrue(isMaglevved(load));
+ assertMaglevved(load);
// We should deopt here.
assertEquals(42.5, load({y:0, float64:42.5}));
- assertFalse(isMaglevved(load));
+ assertNotMaglevved(load);
})();
// Checks simple monomorphic load of a Double field works with a float64 add.
@@ -51,9 +51,9 @@
%OptimizeMaglevOnNextCall(load);
assertEquals(85, load({float64:42.5}));
- assertTrue(isMaglevved(load));
+ assertMaglevved(load);
// We should deopt here.
assertEquals(85, load({y:0, float64:42.5}));
- assertFalse(isMaglevved(load));
+ assertNotMaglevved(load);
})();
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-holey-float.js b/deps/v8/test/mjsunit/maglev/math-max-float64-holey-float.js
index dc3e4e85496..a24d78cd66d 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-holey-float.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-holey-float.js
@@ -21,4 +21,4 @@ assertEquals(5.2, foo(normalArray));
assertTrue(isNaN(foo(holeyArray)));
// No deopts.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-inlined-const.js b/deps/v8/test/mjsunit/maglev/math-max-float64-inlined-const.js
index f40a9a89f57..c9b01450ec7 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-inlined-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-inlined-const.js
@@ -46,4 +46,4 @@ test();
test();
// No deopts.
-assertTrue(isMaglevved(test));
+assertMaglevved(test);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-non-eager-inlined-const.js b/deps/v8/test/mjsunit/maglev/math-max-float64-non-eager-inlined-const.js
index a4beb0116dd..c562f558285 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-non-eager-inlined-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-non-eager-inlined-const.js
@@ -52,7 +52,7 @@ function test(f) {
f();
%OptimizeMaglevOnNextCall(f);
f();
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
}
function testDoubles() {
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-not-const.js b/deps/v8/test/mjsunit/maglev/math-max-float64-not-const.js
index ff445d42e49..ee159a56fb6 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-not-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-not-const.js
@@ -33,4 +33,4 @@ assertSame(Infinity, max2(-Infinity, Infinity));
assertSame(-Infinity, max2(-Infinity, -Infinity));
// No deopts.
-assertTrue(isMaglevved(max2));
+assertMaglevved(max2);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-same-inlining.js b/deps/v8/test/mjsunit/maglev/math-max-float64-same-inlining.js
index 43341a99609..7cfef206737 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-same-inlining.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-same-inlining.js
@@ -14,7 +14,7 @@ testDouble();
%OptimizeMaglevOnNextCall(testDouble);
assertEquals(5.5, testDouble());
-assertTrue(isMaglevved(testDouble));
+assertMaglevved(testDouble);
function testObject() {
let v = {valueOf: () => {return 1.1;}}
@@ -26,4 +26,4 @@ testObject();
%OptimizeMaglevOnNextCall(testObject);
assertEquals(1.1, testObject());
-assertFalse(isMaglevved(testObject));
+assertNotMaglevved(testObject);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-first-param.js b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-first-param.js
index c9b501dd9d3..8828d1d1299 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-first-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-first-param.js
@@ -17,7 +17,7 @@ assertEquals(6.2, max2(6.1, 6.2));
// Passing a non-number will deopt.
assertEquals(1.5, max2(0.5, {valueOf: () => 1.5}));
-assertFalse(isMaglevved(max2));
+assertNotMaglevved(max2);
%OptimizeMaglevOnNextCall(max2);
assertEquals(6.2, max2(6.1, 6.2));
@@ -25,4 +25,4 @@ assertEquals(6.2, max2(6.1, 6.2));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(1.5, max2(0.5, {valueOf: () => 1.5}));
-assertTrue(isMaglevved(max2));
+assertMaglevved(max2);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-only-param.js b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-only-param.js
index 4e6ffd462f7..908d6437c38 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-only-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-only-param.js
@@ -17,7 +17,7 @@ assertEquals(6.1, max1(6.1));
// Passing a non-number will deopt.
assertEquals(1.5, max1({valueOf: () => 1.5}));
-assertFalse(isMaglevved(max1));
+assertNotMaglevved(max1);
%OptimizeMaglevOnNextCall(max1);
assertEquals(6.1, max1(6.1));
@@ -25,4 +25,4 @@ assertEquals(6.1, max1(6.1));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(1.5, max1({valueOf: () => 1.5}));
-assertTrue(isMaglevved(max1));
+assertMaglevved(max1);
diff --git a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-second-param.js b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-second-param.js
index c9b501dd9d3..8828d1d1299 100644
--- a/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-second-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-max-float64-speculation-wrong-second-param.js
@@ -17,7 +17,7 @@ assertEquals(6.2, max2(6.1, 6.2));
// Passing a non-number will deopt.
assertEquals(1.5, max2(0.5, {valueOf: () => 1.5}));
-assertFalse(isMaglevved(max2));
+assertNotMaglevved(max2);
%OptimizeMaglevOnNextCall(max2);
assertEquals(6.2, max2(6.1, 6.2));
@@ -25,4 +25,4 @@ assertEquals(6.2, max2(6.1, 6.2));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(1.5, max2(0.5, {valueOf: () => 1.5}));
-assertTrue(isMaglevved(max2));
+assertMaglevved(max2);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-holey-float.js b/deps/v8/test/mjsunit/maglev/math-min-float64-holey-float.js
index 52a448686f9..de592c82168 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-holey-float.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-holey-float.js
@@ -21,4 +21,4 @@ assertEquals(4.5, foo(normalArray));
assertTrue(isNaN(foo(holeyArray)));
// No deopts.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-inlined-const.js b/deps/v8/test/mjsunit/maglev/math-min-float64-inlined-const.js
index bd5d795a724..20f4933c6ec 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-inlined-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-inlined-const.js
@@ -46,4 +46,4 @@ test();
test();
// No deopts.
-assertTrue(isMaglevved(test));
+assertMaglevved(test);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-non-eager-inlined-const.js b/deps/v8/test/mjsunit/maglev/math-min-float64-non-eager-inlined-const.js
index 76bf363f2a6..d5d2ac16f43 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-non-eager-inlined-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-non-eager-inlined-const.js
@@ -52,7 +52,7 @@ function test(f) {
f();
%OptimizeMaglevOnNextCall(f);
f();
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
}
function testDoubles() {
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-not-const.js b/deps/v8/test/mjsunit/maglev/math-min-float64-not-const.js
index 8cf219ee721..500152efdcf 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-not-const.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-not-const.js
@@ -33,4 +33,4 @@ assertSame(-Infinity, min2(-Infinity, Infinity));
assertSame(-Infinity, min2(-Infinity, -Infinity));
// No deopts.
-assertTrue(isMaglevved(min2));
+assertMaglevved(min2);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-same-inlining.js b/deps/v8/test/mjsunit/maglev/math-min-float64-same-inlining.js
index 27be576f4f5..32bee9f4f1b 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-same-inlining.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-same-inlining.js
@@ -14,7 +14,7 @@ testDouble();
%OptimizeMaglevOnNextCall(testDouble);
assertEquals(5.5, testDouble());
-assertTrue(isMaglevved(testDouble));
+assertMaglevved(testDouble);
function testObject() {
let v = {valueOf: () => {return 1.1;}}
@@ -26,4 +26,4 @@ testObject();
%OptimizeMaglevOnNextCall(testObject);
assertEquals(1.1, testObject());
-assertFalse(isMaglevved(testObject));
+assertNotMaglevved(testObject);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-first-param.js b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-first-param.js
index a99879de173..ec977684c53 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-first-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-first-param.js
@@ -17,7 +17,7 @@ assertEquals(6.1, min2(6.1, 6.2));
// Passing a non-number will deopt.
assertEquals(0.5, min2({valueOf: () => 1.5}, 0.5));
-assertFalse(isMaglevved(min2));
+assertNotMaglevved(min2);
%OptimizeMaglevOnNextCall(min2);
assertEquals(6.1, min2(6.1, 6.2));
@@ -25,4 +25,4 @@ assertEquals(6.1, min2(6.1, 6.2));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(0.5, min2({valueOf: () => 1.5}, 0.5));
-assertTrue(isMaglevved(min2));
+assertMaglevved(min2);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-only-param.js b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-only-param.js
index 2d242d45c33..20a383ab0ad 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-only-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-only-param.js
@@ -17,7 +17,7 @@ assertEquals(6.1, min1(6.1));
// Passing a non-number will deopt.
assertEquals(1.5, min1({valueOf: () => 1.5}));
-assertFalse(isMaglevved(min1));
+assertNotMaglevved(min1);
%OptimizeMaglevOnNextCall(min1);
assertEquals(6.1, min1(6.1));
@@ -25,4 +25,4 @@ assertEquals(6.1, min1(6.1));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(1.5, min1({valueOf: () => 1.5}));
-assertTrue(isMaglevved(min1));
+assertMaglevved(min1);
diff --git a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-second-param.js b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-second-param.js
index d22e5948b56..06d8dba82ca 100644
--- a/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-second-param.js
+++ b/deps/v8/test/mjsunit/maglev/math-min-float64-speculation-wrong-second-param.js
@@ -17,7 +17,7 @@ assertEquals(6.1, min2(6.1, 6.2));
// Passing a non-number will deopt.
assertEquals(0.5, min2(0.5, {valueOf: () => 1.5}));
-assertFalse(isMaglevved(min2));
+assertNotMaglevved(min2);
%OptimizeMaglevOnNextCall(min2);
assertEquals(6.1, min2(6.1, 6.2));
@@ -25,4 +25,4 @@ assertEquals(6.1, min2(6.1, 6.2));
// No we no longer speculate on the argument type being float64, so we also
// don't deopt.
assertEquals(0.5, min2(0.5, {valueOf: () => 1.5}));
-assertTrue(isMaglevved(min2));
+assertMaglevved(min2);
diff --git a/deps/v8/test/mjsunit/maglev/negate.js b/deps/v8/test/mjsunit/maglev/negate.js
index 3afd46541a7..7c945bb1a17 100644
--- a/deps/v8/test/mjsunit/maglev/negate.js
+++ b/deps/v8/test/mjsunit/maglev/negate.js
@@ -15,7 +15,7 @@ function test_negate_int32(value, expected) {
negate(1, -1);
%OptimizeMaglevOnNextCall(negate);
assertEquals(expected, negate(value));
- assertTrue(isMaglevved(negate));
+ assertMaglevved(negate);
%DeoptimizeFunction(negate);
assertEquals(expected, negate(value));
@@ -33,7 +33,7 @@ function test_negate_float(value, expected) {
negate(1.1, -1.1);
%OptimizeMaglevOnNextCall(negate);
assertEquals(expected, negate(value));
- assertTrue(isMaglevved(negate));
+ assertMaglevved(negate);
%DeoptimizeFunction(negate);
assertEquals(expected, negate(value));
@@ -56,7 +56,7 @@ function test_negate_int32_expect_deopt(value, expected) {
negate(12, -12);
%OptimizeMaglevOnNextCall(negate);
assertEquals(expected, negate(value));
- assertFalse(isMaglevved(negate));
+ assertNotMaglevved(negate);
}
// -0 is not an int32
diff --git a/deps/v8/test/mjsunit/maglev/new-closure-tenured.js b/deps/v8/test/mjsunit/maglev/new-closure-tenured.js
index 12b5b330d1d..a13d0819fb0 100644
--- a/deps/v8/test/mjsunit/maglev/new-closure-tenured.js
+++ b/deps/v8/test/mjsunit/maglev/new-closure-tenured.js
@@ -20,4 +20,4 @@ o = create_closure(7);
o = create_closure(7);
assertEquals(7+4+2+2, o.x(2));
assertEquals(7+5+2+5, o.x(5));
-assertTrue(isMaglevved(create_closure));
+assertMaglevved(create_closure);
diff --git a/deps/v8/test/mjsunit/maglev/no-deopt-deprecated-map.js b/deps/v8/test/mjsunit/maglev/no-deopt-deprecated-map.js
index fdc05ba2ac0..c4b70079613 100644
--- a/deps/v8/test/mjsunit/maglev/no-deopt-deprecated-map.js
+++ b/deps/v8/test/mjsunit/maglev/no-deopt-deprecated-map.js
@@ -33,9 +33,9 @@ foo(o3); // Make it polymorphic.
%OptimizeMaglevOnNextCall(foo);
foo(o2_1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Calling foo with a deprecated map should not deopt.
foo(o1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/omit-default-ctors-array-iterator.js b/deps/v8/test/mjsunit/maglev/omit-default-ctors-array-iterator.js
index 2d66f99bca6..b7856f88959 100644
--- a/deps/v8/test/mjsunit/maglev/omit-default-ctors-array-iterator.js
+++ b/deps/v8/test/mjsunit/maglev/omit-default-ctors-array-iterator.js
@@ -27,7 +27,7 @@
// C default ctor doing "...args" and B default ctor doing "...args"
// do *not* use the iterator.
assertEquals(0, iterationCount);
- assertTrue(isMaglevved(C)); // No deopt.
+ assertMaglevved(C); // No deopt.
Array.prototype[Symbol.iterator] = oldIterator;
})();
diff --git a/deps/v8/test/mjsunit/maglev/omit-default-ctors.js b/deps/v8/test/mjsunit/maglev/omit-default-ctors.js
index 97788680d24..40b87196da4 100644
--- a/deps/v8/test/mjsunit/maglev/omit-default-ctors.js
+++ b/deps/v8/test/mjsunit/maglev/omit-default-ctors.js
@@ -12,7 +12,7 @@
%OptimizeMaglevOnNextCall(B);
const o = new B();
assertSame(B.prototype, o.__proto__);
- assertTrue(isMaglevved(B)); // No deopt.
+ assertMaglevved(B); // No deopt.
})();
(function OmitDefaultDerivedCtor() {
@@ -24,7 +24,7 @@
%OptimizeMaglevOnNextCall(C);
const o = new C();
assertSame(C.prototype, o.__proto__);
- assertTrue(isMaglevved(C)); // No deopt.
+ assertMaglevved(C); // No deopt.
})();
(function OmitDefaultBaseAndDerivedCtor() {
@@ -36,7 +36,7 @@
%OptimizeMaglevOnNextCall(C);
const o = new C();
assertSame(C.prototype, o.__proto__);
- assertTrue(isMaglevved(C)); // No deopt.
+ assertMaglevved(C); // No deopt.
})();
(function OmitDefaultBaseCtorWithExplicitSuper() {
@@ -47,7 +47,7 @@
%OptimizeMaglevOnNextCall(B);
const o = new B();
assertSame(B.prototype, o.__proto__);
- assertTrue(isMaglevved(B)); // No deopt.
+ assertMaglevved(B); // No deopt.
})();
(function OmitDefaultDerivedCtorWithExplicitSuper() {
@@ -59,7 +59,7 @@
%OptimizeMaglevOnNextCall(C);
const o = new C();
assertSame(C.prototype, o.__proto__);
- assertTrue(isMaglevved(C)); // No deopt.
+ assertMaglevved(C); // No deopt.
})();
(function OmitDefaultBaseAndDerivedCtorWithExplicitSuper() {
@@ -71,7 +71,7 @@
%OptimizeMaglevOnNextCall(C);
const o = new C();
assertSame(C.prototype, o.__proto__);
- assertTrue(isMaglevved(C)); // No deopt.
+ assertMaglevved(C); // No deopt.
})();
(function OmitDefaultBaseCtorWithExplicitSuperAndNonFinalSpread() {
@@ -83,9 +83,9 @@
const o = new B(3, 4);
assertSame(B.prototype, o.__proto__);
// See https://bugs.chromium.org/p/v8/issues/detail?id=13337
- // assertTrue(isMaglevved(B)); // No deopt.
+ // assertMaglevved(B); // No deopt.
// This assert will fail when the above bug is fixed:
- assertFalse(isMaglevved(B));
+ assertNotMaglevved(B);
})();
(function OmitDefaultDerivedCtorWithExplicitSuperAndNonFinalSpread() {
@@ -98,9 +98,9 @@
const o = new C(3, 4);
assertSame(C.prototype, o.__proto__);
// See https://bugs.chromium.org/p/v8/issues/detail?id=13337
- // assertTrue(isMaglevved(C)); // No deopt.
+ // assertMaglevved(C); // No deopt.
// This assert will fail when the above bug is fixed:
- assertFalse(isMaglevved(C));
+ assertNotMaglevved(C);
})();
(function OmitDefaultBaseAndDerivedCtorWithExplicitSuperAndNonFinalSpread() {
@@ -113,9 +113,9 @@
const o = new C(3, 4);
assertSame(C.prototype, o.__proto__);
// See https://bugs.chromium.org/p/v8/issues/detail?id=13337
- // assertTrue(isMaglevved(C)); // No deopt.
+ // assertMaglevved(C); // No deopt.
// This assert will fail when the above bug is fixed:
- assertFalse(isMaglevved(C));
+ assertNotMaglevved(C);
})();
(function NonDefaultBaseConstructorCalled() {
@@ -137,7 +137,7 @@
assertEquals(2, ctorCallCount);
assertEquals([1, 2, 3], lastArgs);
assertTrue(a.baseTagged);
- assertTrue(isMaglevved(A)); // No deopt.
+ assertMaglevved(A); // No deopt.
// 'A' default ctor will be omitted.
class B1 extends A {};
@@ -148,7 +148,7 @@
assertEquals(4, ctorCallCount);
assertEquals([4, 5, 6], lastArgs);
assertTrue(b1.baseTagged);
- assertTrue(isMaglevved(B1)); // No deopt.
+ assertMaglevved(B1); // No deopt.
// The same test with non-final spread; 'A' default ctor will be omitted.
class B2 extends A {
@@ -162,9 +162,9 @@
assertEquals([1, 4, 5, 6, 2], lastArgs);
assertTrue(b2.baseTagged);
// See https://bugs.chromium.org/p/v8/issues/detail?id=13337
- // assertTrue(isMaglevved(B2)); // No deopt.
+ // assertMaglevved(B2); // No deopt.
// This assert will fail when the above bug is fixed:
- assertFalse(isMaglevved(B2)); // No deopt.
+ assertNotMaglevved(B2); // No deopt.
})();
(function NonDefaultDerivedConstructorCalled() {
@@ -188,7 +188,7 @@
assertEquals(2, ctorCallCount);
assertEquals([1, 2, 3], lastArgs);
assertTrue(a.derivedTagged);
- assertTrue(isMaglevved(A)); // No deopt.
+ assertMaglevved(A); // No deopt.
// 'A' default ctor will be omitted.
class B1 extends A {};
@@ -199,7 +199,7 @@
assertEquals(4, ctorCallCount);
assertEquals([4, 5, 6], lastArgs);
assertTrue(b1.derivedTagged);
- assertTrue(isMaglevved(B1)); // No deopt.
+ assertMaglevved(B1); // No deopt.
// The same test with non-final spread. 'A' default ctor will be omitted.
class B2 extends A {
@@ -213,9 +213,9 @@
assertEquals([1, 4, 5, 6, 2], lastArgs);
assertTrue(b2.derivedTagged);
// See https://bugs.chromium.org/p/v8/issues/detail?id=13337
- // assertTrue(isMaglevved(B2)); // No deopt.
+ // assertMaglevved(B2); // No deopt.
// This assert will fail when the above bug is fixed:
- assertFalse(isMaglevved(B2)); // No deopt.
+ assertNotMaglevved(B2); // No deopt.
})();
(function BaseFunctionCalled() {
@@ -232,7 +232,7 @@
const a1 = new A1();
assertEquals(2, baseFunctionCallCount);
assertTrue(a1.baseTagged);
- assertTrue(isMaglevved(A1)); // No deopt.
+ assertMaglevved(A1); // No deopt.
class A2 extends BaseFunction {
constructor(...args) { super(1, ...args, 2); }
@@ -243,7 +243,7 @@
const a2 = new A2();
assertEquals(4, baseFunctionCallCount);
assertTrue(a2.baseTagged);
- assertTrue(isMaglevved(A2)); // No deopt.
+ assertMaglevved(A2); // No deopt.
})();
(function NonSuperclassCtor() {
@@ -379,7 +379,7 @@
new D();
assertEquals(2, fooCallCount);
assertEquals(1, ctorCallCount);
- assertFalse(isMaglevved(D));
+ assertNotMaglevved(D);
})();
// The same test as the previous one, but with a ctor with a non-final spread.
@@ -417,7 +417,7 @@
new D();
assertEquals(2, fooCallCount);
assertEquals(1, ctorCallCount);
- assertFalse(isMaglevved(D));
+ assertNotMaglevved(D);
})();
(function BasePrivateField() {
@@ -437,7 +437,7 @@
const b = new B();
assertTrue(b.isA());
- assertTrue(isMaglevved(B)); // No deopt.
+ assertMaglevved(B); // No deopt.
%PrepareFunctionForOptimization(C1);
new C1();
@@ -445,7 +445,7 @@
const c1 = new C1();
assertTrue(c1.isA());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -453,7 +453,7 @@
const c2 = new C2();
assertTrue(c2.isA());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function DerivedPrivateField() {
@@ -473,7 +473,7 @@
const c1 = new C1();
assertTrue(c1.isB());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -481,7 +481,7 @@
const c2 = new C2();
assertTrue(c2.isB());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function BasePrivateMethod() {
@@ -501,7 +501,7 @@
const b = new B();
assertEquals('private', b.callPrivate());
- assertTrue(isMaglevved(B)); // No deopt.
+ assertMaglevved(B); // No deopt.
%PrepareFunctionForOptimization(C1);
new C1();
@@ -509,7 +509,7 @@
const c1 = new C1();
assertEquals('private', c1.callPrivate());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -517,7 +517,7 @@
const c2 = new C2();
assertEquals('private', c2.callPrivate());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function DerivedPrivateMethod() {
@@ -537,7 +537,7 @@
const c1 = new C1();
assertEquals('private', c1.callPrivate());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -545,7 +545,7 @@
const c2 = new C2();
assertEquals('private', c2.callPrivate());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function BasePrivateGetter() {
@@ -565,7 +565,7 @@
const b = new B();
assertEquals('private', b.getPrivate());
- assertTrue(isMaglevved(B)); // No deopt.
+ assertMaglevved(B); // No deopt.
%PrepareFunctionForOptimization(C1);
new C1();
@@ -573,7 +573,7 @@
const c1 = new C1();
assertEquals('private', c1.getPrivate());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -581,7 +581,7 @@
const c2 = new C2();
assertEquals('private', c2.getPrivate());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function DerivedPrivateGetter() {
@@ -601,7 +601,7 @@
const c1 = new C1();
assertEquals('private', c1.getPrivate());
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -609,7 +609,7 @@
const c2 = new C2();
assertEquals('private', c2.getPrivate());
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function BasePrivateSetter() {
@@ -638,7 +638,7 @@
const c1 = new C1();
c1.setPrivate();
assertEquals('private', c1.secret);
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -647,7 +647,7 @@
const c2 = new C2();
c2.setPrivate();
assertEquals('private', c2.secret);
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function DerivedPrivateSetter() {
@@ -668,7 +668,7 @@
const c1 = new C1();
c1.setPrivate();
assertEquals('private', c1.secret);
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -677,7 +677,7 @@
const c2 = new C2();
c2.setPrivate();
assertEquals('private', c2.secret);
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function BaseClassFields() {
@@ -701,7 +701,7 @@
const c1 = new C1();
assertTrue(c1.aField);
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -709,7 +709,7 @@
const c2 = new C2();
assertTrue(c2.aField);
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
(function DerivedClassFields() {
@@ -726,7 +726,7 @@
const c1 = new C1();
assertTrue(c1.bField);
- assertTrue(isMaglevved(C1)); // No deopt.
+ assertMaglevved(C1); // No deopt.
%PrepareFunctionForOptimization(C2);
new C2();
@@ -734,5 +734,5 @@
const c2 = new C2();
assertTrue(c2.bField);
- assertTrue(isMaglevved(C2)); // No deopt.
+ assertMaglevved(C2); // No deopt.
})();
diff --git a/deps/v8/test/mjsunit/maglev/poly-calls-1.js b/deps/v8/test/mjsunit/maglev/poly-calls-1.js
index 0bf2bd2c86f..1bd168e851b 100644
--- a/deps/v8/test/mjsunit/maglev/poly-calls-1.js
+++ b/deps/v8/test/mjsunit/maglev/poly-calls-1.js
@@ -38,8 +38,8 @@ foo(o2);
assertEquals(128, foo(o1));
assertEquals(256, foo(o2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
let somethingElse = {foo: () => {return -8}};
assertEquals(-8, foo(somethingElse));
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/poly-calls-2.js b/deps/v8/test/mjsunit/maglev/poly-calls-2.js
index 653397ea1ce..a7b4812f5f1 100644
--- a/deps/v8/test/mjsunit/maglev/poly-calls-2.js
+++ b/deps/v8/test/mjsunit/maglev/poly-calls-2.js
@@ -49,10 +49,10 @@ assertEquals(256 + 20, foo(o2));
outsideObject.a = 10;
assertEquals(128 + 10, foo(o1));
assertEquals(256 + 10, foo(o2));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Change the map of `outsideObject`; this will also deopt.
outsideObject = {aa: 0, a: 0};
assertEquals(128, foo(o1));
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/poly-store-transition.js b/deps/v8/test/mjsunit/maglev/poly-store-transition.js
index cd87e812d5e..1c88260e3f2 100644
--- a/deps/v8/test/mjsunit/maglev/poly-store-transition.js
+++ b/deps/v8/test/mjsunit/maglev/poly-store-transition.js
@@ -29,4 +29,4 @@ assertTrue(%HasDoubleElements(c));
poly_store(c, 'a');
assertTrue(%HasObjectElements(c));
assertEquals(c[0], 'a');
-assertTrue(isMaglevved(poly_store));
+assertMaglevved(poly_store);
diff --git a/deps/v8/test/mjsunit/maglev/polymorphic-store.js b/deps/v8/test/mjsunit/maglev/polymorphic-store.js
index 0e51fea6d52..ccef0a64b84 100644
--- a/deps/v8/test/mjsunit/maglev/polymorphic-store.js
+++ b/deps/v8/test/mjsunit/maglev/polymorphic-store.js
@@ -22,9 +22,9 @@ f(o3, 2);
assertEquals(1, o1.x);
assertEquals(2, o3.x);
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
let o4 = {a: 0, b: 0, c: 0, x: 0};
f(o4, 3);
-assertFalse(isMaglevved(f));
+assertNotMaglevved(f);
assertEquals(3, o4.x);
diff --git a/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js b/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js
index 9d6c244560a..ab2843e084d 100644
--- a/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js
+++ b/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js
@@ -22,7 +22,7 @@
%OptimizeMaglevOnNextCall(catchTest);
assertEquals(42, await catchTest(Promise.resolve(42)));
assertEquals(-5, await catchTest(Promise.reject(5)));
- assertTrue(isMaglevved(catchTest));
+ assertMaglevved(catchTest);
}
// 2. Non-callable reaction behaves like identity.
@@ -35,7 +35,7 @@
assertEquals(10, await nonCallableCatch(Promise.resolve(10)));
%OptimizeMaglevOnNextCall(nonCallableCatch);
assertEquals(10, await nonCallableCatch(Promise.resolve(10)));
- assertTrue(isMaglevved(nonCallableCatch));
+ assertMaglevved(nonCallableCatch);
}
// 3. Subclassed promise receiver.
@@ -53,7 +53,7 @@
const p2 = subCatch(MyPromise.reject(3));
assertInstanceof(p2, MyPromise);
assertEquals(-3, await p2);
- assertTrue(isMaglevved(subCatch));
+ assertMaglevved(subCatch);
}
// 4. Chained catch handler.
@@ -67,7 +67,7 @@
%OptimizeMaglevOnNextCall(chainedCatch);
assertEquals(10, await chainedCatch(Promise.resolve(10)));
assertEquals(6, await chainedCatch(Promise.reject(5)));
- assertTrue(isMaglevved(chainedCatch));
+ assertMaglevved(chainedCatch);
}
// 5. Catch with zero arguments (on_rejected defaults to undefined).
@@ -96,7 +96,7 @@
assertEquals(5, e);
}
assertTrue(caught);
- assertTrue(isMaglevved(zeroArgsCatch));
+ assertMaglevved(zeroArgsCatch);
}
// 6. Catch with extra arguments (extra arguments are ignored).
@@ -110,7 +110,7 @@
%OptimizeMaglevOnNextCall(extraArgsCatch);
assertEquals(42, await extraArgsCatch(Promise.resolve(42)));
assertEquals(-5, await extraArgsCatch(Promise.reject(5)));
- assertTrue(isMaglevved(extraArgsCatch));
+ assertMaglevved(extraArgsCatch);
}
// 7. Spread call p.catch(...args) (skips reduction and falls back to generic call).
@@ -126,7 +126,7 @@
assertEquals(42, await spreadCatch(Promise.resolve(42), [e => -e]));
assertEquals(-5, await spreadCatch(Promise.reject(5), [e => -e]));
assertEquals(42, await spreadCatch(Promise.resolve(42), []));
- assertTrue(isMaglevved(spreadCatch));
+ assertMaglevved(spreadCatch);
}
// 8. Reduction registers a dependency on PromiseThenProtector.
@@ -142,7 +142,7 @@
testThenProtector(p);
%OptimizeMaglevOnNextCall(testThenProtector);
testThenProtector(p);
- assertTrue(isMaglevved(testThenProtector));
+ assertMaglevved(testThenProtector);
// Invalidate PromiseThenProtector.
Promise.prototype.then = function() {
@@ -157,6 +157,6 @@
testThenProtector(p);
%OptimizeMaglevOnNextCall(testThenProtector);
assertEquals('patched', testThenProtector(p));
- assertTrue(isMaglevved(testThenProtector));
+ assertMaglevved(testThenProtector);
}
})();
diff --git a/deps/v8/test/mjsunit/maglev/promise-resolve-inline.js b/deps/v8/test/mjsunit/maglev/promise-resolve-inline.js
index aacbbc375b3..d9aa7458a52 100644
--- a/deps/v8/test/mjsunit/maglev/promise-resolve-inline.js
+++ b/deps/v8/test/mjsunit/maglev/promise-resolve-inline.js
@@ -20,7 +20,7 @@
%OptimizeMaglevOnNextCall(foo);
assertEquals(42, await foo(42));
assertEquals(undefined, await Promise.resolve());
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const p = foo(42);
assertInstanceof(p, Promise);
assertEquals(42, await p);
@@ -38,7 +38,7 @@
assertEquals(obj, await foo(obj));
%OptimizeMaglevOnNextCall(foo);
assertEquals(obj, await foo(obj));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// A thenable must not be reduced: chaining runs, so we observe 42.
@@ -53,7 +53,7 @@
assertEquals(42, await foo(thenable));
%OptimizeMaglevOnNextCall(foo);
assertEquals(42, await foo(thenable));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// A promise value keeps its identity (promise maps have "then", so the
@@ -68,7 +68,7 @@
assertSame(p, foo(p));
%OptimizeMaglevOnNextCall(foo);
assertSame(p, foo(p));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// A promise whose prototype chain was mutated to lack "then" but keep
@@ -86,7 +86,7 @@
assertSame(weird, foo(weird));
%OptimizeMaglevOnNextCall(foo);
assertSame(weird, foo(weird));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// Subclass receivers are not reduced: the species-less fast path only
@@ -102,6 +102,6 @@
%OptimizeMaglevOnNextCall(foo);
assertInstanceof(foo(3), MyPromise);
assertEquals(3, await foo(3));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
})();
diff --git a/deps/v8/test/mjsunit/maglev/regress-410867001.js b/deps/v8/test/mjsunit/maglev/regress-410867001.js
index 82b753167d8..f2fb17f9df7 100644
--- a/deps/v8/test/mjsunit/maglev/regress-410867001.js
+++ b/deps/v8/test/mjsunit/maglev/regress-410867001.js
@@ -13,11 +13,11 @@ const v1 = new String();
foo(v0, v1);
%OptimizeMaglevOnNextCall(foo);
foo(v0, v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// This will invalidate the StringWrapperToPrimitive protector.
Reflect.construct(v1.constructor, v1, Int16Array);
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
v1.valueOf = () => ' 2';
assertEquals('1 2', foo(v0, v1));
diff --git a/deps/v8/test/mjsunit/maglev/regress-457475186.js b/deps/v8/test/mjsunit/maglev/regress-457475186.js
index f4b74b03451..b3a8ee8a65e 100644
--- a/deps/v8/test/mjsunit/maglev/regress-457475186.js
+++ b/deps/v8/test/mjsunit/maglev/regress-457475186.js
@@ -16,5 +16,5 @@ foo(0);
%OptimizeMaglevOnNextCall(foo);
foo(0);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(0, x);
diff --git a/deps/v8/test/mjsunit/maglev/regress-498816446-3.js b/deps/v8/test/mjsunit/maglev/regress-498816446-3.js
index 3eded897758..6d3975fafa9 100644
--- a/deps/v8/test/mjsunit/maglev/regress-498816446-3.js
+++ b/deps/v8/test/mjsunit/maglev/regress-498816446-3.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --maglev-object-tracking --maglev
+// Flags: --allow-natives-syntax --maglev-object-tracking --maglev --mock-arraybuffer-allocator
let ta = new Int32Array(4);
diff --git a/deps/v8/test/mjsunit/maglev/regress-500507435.js b/deps/v8/test/mjsunit/maglev/regress-500507435.js
index d1c30c0f747..60188c1f7c3 100644
--- a/deps/v8/test/mjsunit/maglev/regress-500507435.js
+++ b/deps/v8/test/mjsunit/maglev/regress-500507435.js
@@ -27,4 +27,4 @@ assertEquals(255, store(arr, 255.0));
assertEquals(0, store(arr, -0.3));
assertEquals(0, store(arr, NaN));
-assertTrue(isMaglevved(store));
+assertMaglevved(store);
diff --git a/deps/v8/test/mjsunit/maglev/regress-521604719.js b/deps/v8/test/mjsunit/maglev/regress-521604719.js
index c4b7a13eaca..cf7e2bc93c0 100644
--- a/deps/v8/test/mjsunit/maglev/regress-521604719.js
+++ b/deps/v8/test/mjsunit/maglev/regress-521604719.js
@@ -4,6 +4,7 @@
// Flags: --allow-natives-syntax --no-lazy-feedback-allocation
// Flags: --no-concurrent-osr --no-maglev-optimistic-peeled-loops
+// Flags: --mock-arraybuffer-allocator
function test() {
%OptimizeOsr();
diff --git a/deps/v8/test/mjsunit/maglev/regress-525348892.js b/deps/v8/test/mjsunit/maglev/regress-525348892.js
index f1e9c43bde8..d9c250fb71c 100644
--- a/deps/v8/test/mjsunit/maglev/regress-525348892.js
+++ b/deps/v8/test/mjsunit/maglev/regress-525348892.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --mock-arraybuffer-allocator
if (%Is64Bit()) {
const ab = new ArrayBuffer(3000000000);
diff --git a/deps/v8/test/mjsunit/maglev/regress-525732296.js b/deps/v8/test/mjsunit/maglev/regress-525732296.js
index f35bf016af7..d3b5e1f373c 100644
--- a/deps/v8/test/mjsunit/maglev/regress-525732296.js
+++ b/deps/v8/test/mjsunit/maglev/regress-525732296.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --maglev
+// Flags: --allow-natives-syntax --maglev --multi-mapped-mock-allocator
const byte_length = 0xFFFFFFFF;
const buffer = new ArrayBuffer(byte_length);
diff --git a/deps/v8/test/mjsunit/maglev/regress-559932543.js b/deps/v8/test/mjsunit/maglev/regress-559932543.js
new file mode 100644
index 00000000000..d8ce1892b95
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-559932543.js
@@ -0,0 +1,135 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev --js-decorators
+
+// Test 1: Private getter accessed in try/catch before class literal
+// finishes evaluating (paused at yield in computed property key).
+(function TestPrivateGetterBeforeYield() {
+ let gen;
+ let object;
+ let exported;
+ function advance(resume) {
+ if (resume) {
+ const result = gen.next();
+ object = new result.value();
+ }
+ }
+ function* maker() {
+ class C {
+ get #m() { return 42; }
+ [(exported = function access(receiver, resume) {
+ try { receiver.#m; } catch (e) {}
+ advance(resume);
+ try { return object.#m; } catch (e) { return "caught"; }
+ }, yield exported, "x")] = 1;
+ }
+ return C;
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ const C = gen.next().value;
+ object = new C();
+ assertEquals(42, access(object, false));
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ advance(true);
+ assertEquals(42, access(object, false));
+ }
+ gen = maker();
+ const access = gen.next().value;
+ object = {};
+ %PrepareFunctionForOptimization(access);
+ for (let i = 0; i < 10; ++i) {
+ assertEquals("caught", access({}, false));
+ }
+ %OptimizeFunctionOnNextCall(access);
+ assertEquals("caught", access({}, false));
+ assertEquals(42, access({}, true));
+})();
+
+// Test 2: Private setter accessed in try/catch before class literal
+// finishes evaluating.
+(function TestPrivateSetterBeforeYield() {
+ let gen;
+ let object;
+ let exported;
+ let stored = 0;
+ function advance(resume) {
+ if (resume) {
+ const result = gen.next();
+ object = new result.value();
+ }
+ }
+ function* maker() {
+ class C {
+ set #m(v) { stored = v; }
+ [(exported = function access(receiver, resume) {
+ try { receiver.#m = 1; } catch (e) {}
+ advance(resume);
+ try { object.#m = 99; return stored; } catch (e) { return "caught"; }
+ }, yield exported, "x")] = 1;
+ }
+ return C;
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ advance(true);
+ assertEquals(99, access(object, false));
+ }
+ gen = maker();
+ const access = gen.next().value;
+ object = {};
+ %PrepareFunctionForOptimization(access);
+ for (let i = 0; i < 10; ++i) {
+ assertEquals("caught", access({}, false));
+ }
+ %OptimizeFunctionOnNextCall(access);
+ assertEquals("caught", access({}, false));
+ assertEquals(99, access({}, true));
+})();
+
+// Test 3: Private auto-accessor accessed in try/catch before yield.
+(function TestPrivateAutoAccessorBeforeYield() {
+ let gen;
+ let object;
+ let exported;
+ function advance(resume) {
+ if (resume) {
+ const result = gen.next();
+ object = new result.value();
+ }
+ }
+ function* maker() {
+ class C {
+ accessor #m = 10;
+ [(exported = function access(receiver, resume) {
+ try { receiver.#m; } catch (e) {}
+ advance(resume);
+ try { return object.#m; } catch (e) { return "caught"; }
+ }, yield exported, "x")] = 1;
+ }
+ return C;
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ advance(true);
+ assertEquals(10, access(object, false));
+ }
+ gen = maker();
+ const access = gen.next().value;
+ object = {};
+ %PrepareFunctionForOptimization(access);
+ for (let i = 0; i < 10; ++i) {
+ assertEquals("caught", access({}, false));
+ }
+ %OptimizeFunctionOnNextCall(access);
+ assertEquals("caught", access({}, false));
+ assertEquals(10, access({}, true));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/regress-560408014.js b/deps/v8/test/mjsunit/maglev/regress-560408014.js
new file mode 100644
index 00000000000..7c229f15758
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-560408014.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev-non-eager-inlining
+// Flags: --maglev-disable-builtin-reducers
+// Flags: --max-maglev-eager-inlined-bytecode-size=0
+
+// {f} is not inlined eagerly by the graph builder, so that the Maglev graph
+// optimizer runs on {main}'s graph in order to inline it late. While walking
+// that graph, the optimizer also reduces the {entries} calls into inlined
+// allocations of array iterators.
+function f() {}
+
+function main() {
+ f();
+ // The array literals are inlined allocations created by the graph builder.
+ // The iterator allocated for the second {entries} call must not be folded
+ // into the allocation block of the first iterator, since the second array
+ // literal allocates in between (and could thus trigger a GC, after which
+ // the first block is not the most recent young allocation anymore).
+ [].entries();
+ [].entries();
+}
+
+%PrepareFunctionForOptimization(f);
+%PrepareFunctionForOptimization(main);
+main();
+%OptimizeMaglevOnNextCall(main);
+main();
diff --git a/deps/v8/test/mjsunit/maglev/regress/regress-1405651.js b/deps/v8/test/mjsunit/maglev/regress/regress-1405651.js
index a563e04f01d..2ac7100f1b2 100644
--- a/deps/v8/test/mjsunit/maglev/regress/regress-1405651.js
+++ b/deps/v8/test/mjsunit/maglev/regress/regress-1405651.js
@@ -4,10 +4,6 @@
//
// Flags: --allow-natives-syntax --harmony --maglev
-function assertMaglevved(f) {
- assertTrue(isMaglevved(f));
-}
-
function f(x) {
return x[2];
}
diff --git a/deps/v8/test/mjsunit/maglev/resolve-promise-elide-then.js b/deps/v8/test/mjsunit/maglev/resolve-promise-elide-then.js
index 549d5e41bcf..6f712299379 100644
--- a/deps/v8/test/mjsunit/maglev/resolve-promise-elide-then.js
+++ b/deps/v8/test/mjsunit/maglev/resolve-promise-elide-then.js
@@ -21,7 +21,7 @@
assertEquals(obj, await foo(obj));
%OptimizeMaglevOnNextCall(foo);
assertEquals(obj, await foo(obj));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// Heap-constant path: a context constant, which map inference doesn't reach.
@@ -40,7 +40,7 @@
assertEquals(a, await foo());
%OptimizeMaglevOnNextCall(foo);
assertEquals(a, await foo());
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
// Destabilize the resolution's map via a sibling sharing the initial map.
const {a: sibling} = make();
@@ -63,7 +63,7 @@
assertEquals(42, await foo(thenable));
%OptimizeMaglevOnNextCall(foo);
assertEquals(42, await foo(thenable));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
// Self-resolution: a promise has "then", so the reduction never fires and the
@@ -82,7 +82,7 @@
await assertThrowsAsync(drive(), TypeError);
%OptimizeMaglevOnNextCall(f);
await assertThrowsAsync(drive(), TypeError);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
}
// Self-resolution with a mutated prototype chain: the resolution has no
@@ -119,6 +119,6 @@
const r = await settled(drive());
assertEquals("rejected", r.status);
assertInstanceof(r.error, TypeError);
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
}
})();
diff --git a/deps/v8/test/mjsunit/maglev/script-context-specialization.js b/deps/v8/test/mjsunit/maglev/script-context-specialization.js
new file mode 100644
index 00000000000..70c784621b3
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/script-context-specialization.js
@@ -0,0 +1,56 @@
+// Copyright 2026 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.
+
+// Flags: --always-specialize-for-script-context --maglev
+// Flags: --allow-natives-syntax
+
+const scriptConst = 42;
+
+function createClosure() {
+ return function foo() {
+ return scriptConst;
+ };
+}
+
+// Create the closure twice to avoid function context specialization.
+const f1 = createClosure();
+const f2 = createClosure();
+
+%PrepareFunctionForOptimization(f1);
+assertEquals(42, f1());
+%OptimizeMaglevOnNextCall(f1);
+assertEquals(42, f1());
+assertMaglevved(f1);
+
+%PrepareFunctionForOptimization(f2);
+assertEquals(42, f2());
+%OptimizeMaglevOnNextCall(f2);
+assertEquals(42, f2());
+assertMaglevved(f2);
+
+function createClosure2() {
+ return function bar() {
+ return scriptConst;
+ };
+}
+
+// Create and optimize the first closure (with function context specialization),
+// then create and optimize a second closure (transitioning from
+// one_closure_cell to many_closures_cell and recompiling without function
+// context specialization).
+const g1 = createClosure2();
+%PrepareFunctionForOptimization(g1);
+assertEquals(42, g1());
+%OptimizeMaglevOnNextCall(g1);
+assertEquals(42, g1());
+assertMaglevved(g1);
+
+const g2 = createClosure2();
+%PrepareFunctionForOptimization(g2);
+assertEquals(42, g2());
+%OptimizeMaglevOnNextCall(g2);
+assertEquals(42, g2());
+assertMaglevved(g2);
+assertEquals(42, g1());
+assertMaglevved(g1);
diff --git a/deps/v8/test/mjsunit/maglev/set-pending-message.js b/deps/v8/test/mjsunit/maglev/set-pending-message.js
index 8f479dc5526..39f4e09f78e 100644
--- a/deps/v8/test/mjsunit/maglev/set-pending-message.js
+++ b/deps/v8/test/mjsunit/maglev/set-pending-message.js
@@ -19,4 +19,4 @@ assertEquals(foo(), 1);
assertEquals(foo(), 1)
// Maglev will not compile this function now because it has handler table.
// After exceptions are supported in Maglev, we could enable the assert below.
-// assertTrue(isMaglevved(foo));
+// assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/shift-right-logical-smi.js b/deps/v8/test/mjsunit/maglev/shift-right-logical-smi.js
index 6077d3c4ac6..1ee01e92801 100644
--- a/deps/v8/test/mjsunit/maglev/shift-right-logical-smi.js
+++ b/deps/v8/test/mjsunit/maglev/shift-right-logical-smi.js
@@ -18,7 +18,7 @@ function shrl_test(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(shrl);
assertEquals(expected_result, shrl(lhs));
- assertTrue(isMaglevved(shrl));
+ assertMaglevved(shrl);
%DeoptimizeFunction(shrl);
assertEquals(expected_result, shrl(lhs));
@@ -35,7 +35,7 @@ function shrl_test_expect_deopt(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(shrl);
assertEquals(expected_result, shrl(lhs));
- assertFalse(isMaglevved(shrl));
+ assertNotMaglevved(shrl);
}
shrl_test(8, 2, 2);
diff --git a/deps/v8/test/mjsunit/maglev/shift-right-logical.js b/deps/v8/test/mjsunit/maglev/shift-right-logical.js
index 164fd0d057d..b49575b02d0 100644
--- a/deps/v8/test/mjsunit/maglev/shift-right-logical.js
+++ b/deps/v8/test/mjsunit/maglev/shift-right-logical.js
@@ -16,7 +16,7 @@ function shrl_test(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(shrl);
assertEquals(expected_result, shrl(lhs, rhs));
- assertTrue(isMaglevved(shrl));
+ assertMaglevved(shrl);
%DeoptimizeFunction(shrl);
assertEquals(expected_result, shrl(lhs, rhs));
@@ -31,7 +31,7 @@ function shrl_test_expect_deopt(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(shrl);
assertEquals(expected_result, shrl(lhs, rhs));
- assertFalse(isMaglevved(shrl));
+ assertNotMaglevved(shrl);
}
shrl_test(8, 2, 2);
diff --git a/deps/v8/test/mjsunit/maglev/shift-right-smi.js b/deps/v8/test/mjsunit/maglev/shift-right-smi.js
index a395654d147..8452db1008c 100644
--- a/deps/v8/test/mjsunit/maglev/shift-right-smi.js
+++ b/deps/v8/test/mjsunit/maglev/shift-right-smi.js
@@ -18,7 +18,7 @@ function sarl_test(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(sarl);
assertEquals(expected_result, sarl(lhs));
- assertTrue(isMaglevved(sarl));
+ assertMaglevved(sarl);
%DeoptimizeFunction(sarl);
assertEquals(expected_result, sarl(lhs));
@@ -34,7 +34,7 @@ function sarl_test_expect_deopt(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(sarl);
assertEquals(expected_result, sarl(lhs));
- assertFalse(isMaglevved(sarl));
+ assertNotMaglevved(sarl);
}
sarl_test(8, 2, 2);
diff --git a/deps/v8/test/mjsunit/maglev/shift-right.js b/deps/v8/test/mjsunit/maglev/shift-right.js
index d6b97f85af9..a85f466789c 100644
--- a/deps/v8/test/mjsunit/maglev/shift-right.js
+++ b/deps/v8/test/mjsunit/maglev/shift-right.js
@@ -16,7 +16,7 @@ function sarl_test(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(sarl);
assertEquals(expected_result, sarl(lhs, rhs));
- assertTrue(isMaglevved(sarl));
+ assertMaglevved(sarl);
%DeoptimizeFunction(sarl);
assertEquals(expected_result, sarl(lhs, rhs));
@@ -30,7 +30,7 @@ function sarl_test_expect_deopt(lhs, rhs, expected_result) {
%OptimizeMaglevOnNextCall(sarl);
assertEquals(expected_result, sarl(lhs, rhs));
- assertFalse(isMaglevved(sarl));
+ assertNotMaglevved(sarl);
}
sarl_test(8, 2, 2);
diff --git a/deps/v8/test/mjsunit/maglev/spill-double.js b/deps/v8/test/mjsunit/maglev/spill-double.js
index 8c7254a3838..9901aa96286 100644
--- a/deps/v8/test/mjsunit/maglev/spill-double.js
+++ b/deps/v8/test/mjsunit/maglev/spill-double.js
@@ -31,8 +31,8 @@ assertEquals(4.2, f(false, value));
%OptimizeMaglevOnNextCall(f);
assertEquals(4.2, f(false, value));
-assertTrue(isMaglevved(f));
+assertMaglevved(f);
// We should deopt here.
assertEquals(4.2, f(true, value));
-assertFalse(isMaglevved(f));
+assertNotMaglevved(f);
diff --git a/deps/v8/test/mjsunit/maglev/sta-module-variable.mjs b/deps/v8/test/mjsunit/maglev/sta-module-variable.mjs
index eba5c1bd921..bc8fb9087c0 100644
--- a/deps/v8/test/mjsunit/maglev/sta-module-variable.mjs
+++ b/deps/v8/test/mjsunit/maglev/sta-module-variable.mjs
@@ -16,5 +16,5 @@ assertEquals(4, foo(1));
%OptimizeMaglevOnNextCall(foo);
assertEquals(5, foo(1));
assertEquals(6, foo(1));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/static-private-brand-inverted-generator.js b/deps/v8/test/mjsunit/maglev/static-private-brand-inverted-generator.js
new file mode 100644
index 00000000000..e1dd6712433
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/static-private-brand-inverted-generator.js
@@ -0,0 +1,85 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+
+// Test static private method call when brand check runs before class constructor
+// initialization finishes (paused at yield in computed property key).
+(function TestStaticPrivateMethodBeforeYield() {
+ let gen;
+ let cls;
+ let exported;
+ function advance(resume) {
+ if (resume) {
+ cls = gen.next().value;
+ }
+ }
+ function* maker() {
+ class C {
+ static #m() { return 42; }
+ [(exported = function access(receiver, resume) {
+ try { receiver.#m(); } catch (e) {}
+ advance(resume);
+ try { return cls.#m(); } catch (e) { return "caught"; }
+ }, yield exported, "x")] = 1;
+ }
+ return C;
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ advance(true);
+ assertEquals(42, access(cls, false));
+ }
+ gen = maker();
+ const access = gen.next().value;
+ cls = {};
+ %PrepareFunctionForOptimization(access);
+ for (let i = 0; i < 10; ++i) {
+ assertEquals("caught", access({}, false));
+ }
+ %OptimizeFunctionOnNextCall(access);
+ assertEquals("caught", access({}, false));
+ assertEquals(42, access({}, true));
+})();
+
+// Test static private `#m in obj` brand check before class constructor
+// initialization finishes (without throwing an exception).
+(function TestStaticPrivateInBeforeYield() {
+ let gen;
+ let cls;
+ let exported;
+ function advance(resume) {
+ if (resume) {
+ cls = gen.next().value;
+ }
+ }
+ function* maker() {
+ class C {
+ static #m() { return 42; }
+ [(exported = function access(receiver, resume) {
+ let before = #m in receiver;
+ advance(resume);
+ return #m in cls;
+ }, yield exported, "x")] = 1;
+ }
+ return C;
+ }
+ for (let i = 0; i < 10; ++i) {
+ gen = maker();
+ const access = gen.next().value;
+ advance(true);
+ assertTrue(access(cls, false));
+ }
+ gen = maker();
+ const access = gen.next().value;
+ cls = {};
+ %PrepareFunctionForOptimization(access);
+ for (let i = 0; i < 10; ++i) {
+ assertFalse(access({}, false));
+ }
+ %OptimizeFunctionOnNextCall(access);
+ assertFalse(access({}, false));
+ assertTrue(access({}, true));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/store-constant-field-nan.js b/deps/v8/test/mjsunit/maglev/store-constant-field-nan.js
index 6150b63d016..6ec5e187679 100644
--- a/deps/v8/test/mjsunit/maglev/store-constant-field-nan.js
+++ b/deps/v8/test/mjsunit/maglev/store-constant-field-nan.js
@@ -24,6 +24,6 @@ function foo() {
%OptimizeMaglevOnNextCall(foo);
foo(NaN);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(x, NaN);
assertEquals(x, custom_nan);
diff --git a/deps/v8/test/mjsunit/maglev/strict-equals-receiver-or-null-or-undefined.js b/deps/v8/test/mjsunit/maglev/strict-equals-receiver-or-null-or-undefined.js
index a6332d564c8..3aa664073f1 100644
--- a/deps/v8/test/mjsunit/maglev/strict-equals-receiver-or-null-or-undefined.js
+++ b/deps/v8/test/mjsunit/maglev/strict-equals-receiver-or-null-or-undefined.js
@@ -40,8 +40,8 @@ assertFalse(strictEquals(undetectable, undefined));
assertFalse(strictEquals(undetectable, normalObject));
assertTrue(strictEquals(undetectable, undetectable));
-assertTrue(isMaglevved(strictEquals));
+assertMaglevved(strictEquals);
// Passing an unexpected object deopts.
assertFalse(strictEquals({}, ""));
-assertFalse(isMaglevved(strictEquals));
+assertNotMaglevved(strictEquals);
diff --git a/deps/v8/test/mjsunit/maglev/string-compare.js b/deps/v8/test/mjsunit/maglev/string-compare.js
index 2778a03867b..4d9df03d537 100644
--- a/deps/v8/test/mjsunit/maglev/string-compare.js
+++ b/deps/v8/test/mjsunit/maglev/string-compare.js
@@ -29,7 +29,7 @@ function warmUpMaglevTestFn(test_fn_src) {
%OptimizeMaglevOnNextCall(test_fn);
assertEquals(0, test_fn("1", "2"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
return test_fn;
}
@@ -42,23 +42,23 @@ function test(test_fn_src, is_strict=false) {
let test_fn = warmUpMaglevTestFn(test_fn_src);
assertEquals(1, test_fn("1", "1"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(0, test_fn(internalized1234, "1"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
// The GC might have already migrated the thin string, create a new one
let thin1234 = %ConstructThinString( "1234" + "1234" + "1234" + "1234");
assertFalse(%IsInternalizedString(thin1234));
assertEquals(1, test_fn(thin1234, "1234123412341234"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(1, test_fn(thin1234, thin1234));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(1, test_fn(internalized1234, "1234123412341234"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
if (is_strict) {
assertEquals(0, test_fn(internalized1234, 1234123412341234));
diff --git a/deps/v8/test/mjsunit/maglev/string-or-oddball-compare.js b/deps/v8/test/mjsunit/maglev/string-or-oddball-compare.js
index 9ee1015b4fd..ac0a8e6f674 100644
--- a/deps/v8/test/mjsunit/maglev/string-or-oddball-compare.js
+++ b/deps/v8/test/mjsunit/maglev/string-or-oddball-compare.js
@@ -29,7 +29,7 @@ function warmUpMaglevTestFn(test_fn_src) {
%OptimizeMaglevOnNextCall(test_fn);
assertEquals(0, test_fn("1", "2"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
return test_fn;
}
@@ -42,7 +42,7 @@ function test(test_fn_src) {
let test_fn = warmUpMaglevTestFn(test_fn_src);
assertEquals(1, test_fn("1", "1"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(0, test_fn(internalized1234, "1"));
assertEquals(0, test_fn(undefined, "foo"));
@@ -55,20 +55,20 @@ function test(test_fn_src) {
assertEquals(1, test_fn(false, false));
assertEquals(0, test_fn(undefined, null));
assertEquals(0, test_fn(false, true));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
// The GC might have already migrated the thin string, create a new one
let thin1234 = %ConstructThinString( "1234" + "1234" + "1234" + "1234");
assertFalse(%IsInternalizedString(thin1234));
assertEquals(1, test_fn(thin1234, "1234123412341234"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(1, test_fn(thin1234, thin1234));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
assertEquals(1, test_fn(internalized1234, "1234123412341234"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
// Passing something else than a string or oddball will cause a deopt.
assertEquals(0, test_fn(internalized1234, 1234123412341234));
@@ -77,7 +77,7 @@ function test(test_fn_src) {
// Non-internalized strings won't cause a deopt.
test_fn = warmUpMaglevTestFn(test_fn_src);
assertEquals(1, test_fn(nonInternalized1234, "1234123412341234"));
- assertTrue(isMaglevved(test_fn));
+ assertMaglevved(test_fn);
}
function strict_equals_fn(x, y) {
diff --git a/deps/v8/test/mjsunit/maglev/string-slice.js b/deps/v8/test/mjsunit/maglev/string-slice.js
index 7a77cb5e963..710c98f8108 100644
--- a/deps/v8/test/mjsunit/maglev/string-slice.js
+++ b/deps/v8/test/mjsunit/maglev/string-slice.js
@@ -34,7 +34,7 @@ const s2 = "12345";
assertEquals("234", do_slice(s2, 1, 4));
// We should still be in optimized code.
-assertTrue(isMaglevved(do_slice));
+assertMaglevved(do_slice);
function do_slice_1(str, start) {
return str.slice(start);
@@ -43,7 +43,7 @@ function do_slice_1(str, start) {
assertEquals("bcdefg", do_slice_1(s, 1));
%OptimizeMaglevOnNextCall(do_slice_1);
assertEquals("bcdefg", do_slice_1(s, 1));
-assertTrue(isMaglevved(do_slice_1));
+assertMaglevved(do_slice_1);
function do_slice_0(str) {
return str.slice();
@@ -52,8 +52,8 @@ function do_slice_0(str) {
assertEquals(s, do_slice_0(s));
%OptimizeMaglevOnNextCall(do_slice_0);
assertEquals(s, do_slice_0(s));
-assertTrue(isMaglevved(do_slice_0));
+assertMaglevved(do_slice_0);
// Passing something else than a string deopts.
assertEquals("x", do_slice({slice: function() { return "x";}}));
-assertFalse(isMaglevved(do_slice));
+assertNotMaglevved(do_slice);
diff --git a/deps/v8/test/mjsunit/maglev/string-substring.js b/deps/v8/test/mjsunit/maglev/string-substring.js
index 0e06e077f92..f92daa0556c 100644
--- a/deps/v8/test/mjsunit/maglev/string-substring.js
+++ b/deps/v8/test/mjsunit/maglev/string-substring.js
@@ -43,9 +43,9 @@ assertEquals(s.substring(-1), do_substring_1(s, -1)); // clamp to 0
assertEquals(s.substring(100), do_substring_1(s, 100)); // clamp to length
// We should still be in optimized code.
-assertTrue(isMaglevved(do_substring));
-assertTrue(isMaglevved(do_substring_1));
+assertMaglevved(do_substring);
+assertMaglevved(do_substring_1);
// Passing something else than a string deopts.
assertEquals("x", do_substring({substring: function() { return "x";}}, 0, 1));
-assertFalse(isMaglevved(do_substring));
+assertNotMaglevved(do_substring);
diff --git a/deps/v8/test/mjsunit/maglev/string-wrapper-add-1.js b/deps/v8/test/mjsunit/maglev/string-wrapper-add-1.js
index 3259ae46f6f..e22315b8e94 100644
--- a/deps/v8/test/mjsunit/maglev/string-wrapper-add-1.js
+++ b/deps/v8/test/mjsunit/maglev/string-wrapper-add-1.js
@@ -16,19 +16,19 @@ assertEquals('firstsecond', add(string, stringWrapper));
%OptimizeMaglevOnNextCall(add);
assertEquals('firstsecond', add(string, stringWrapper));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
// Also passing the params the other way around is supported (both params are
// of type "string or string wrapper").
assertEquals('secondfirst', add(stringWrapper, string));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
assertEquals('firstfirst', add(string, string));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
assertEquals('secondsecond', add(stringWrapper, stringWrapper));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
// Invalidate the protector.
stringWrapper.valueOf = () => 'third';
diff --git a/deps/v8/test/mjsunit/maglev/string-wrapper-add-2.js b/deps/v8/test/mjsunit/maglev/string-wrapper-add-2.js
index 0c83bf20580..b868300e3a9 100644
--- a/deps/v8/test/mjsunit/maglev/string-wrapper-add-2.js
+++ b/deps/v8/test/mjsunit/maglev/string-wrapper-add-2.js
@@ -17,7 +17,7 @@ assertEquals('firstconstant', add(string));
%OptimizeMaglevOnNextCall(add);
assertEquals('firstconstant', add(string));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
// Invalidate the protector.
stringWrapper.valueOf = () => 'value';
diff --git a/deps/v8/test/mjsunit/maglev/string-wrapper-add-3.js b/deps/v8/test/mjsunit/maglev/string-wrapper-add-3.js
index f37e6b0b66c..5844cfb8eba 100644
--- a/deps/v8/test/mjsunit/maglev/string-wrapper-add-3.js
+++ b/deps/v8/test/mjsunit/maglev/string-wrapper-add-3.js
@@ -16,19 +16,19 @@ assertEquals('firstsecond', add(string, stringWrapper));
%OptimizeMaglevOnNextCall(add);
assertEquals('firstsecond', add(string, stringWrapper));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
// Also passing the params the other way around is supported (both params are
// of type "string or string wrapper").
assertEquals('secondfirst', add(stringWrapper, string));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
assertEquals('firstfirst', add(string, string));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
assertEquals('secondsecond', add(stringWrapper, stringWrapper));
-assertTrue(isMaglevved(add));
+assertMaglevved(add);
// Pass a JSPrimitiveWrapper which is not a string wrapper.
assertEquals('first123', add(string, new Number(123)));
diff --git a/deps/v8/test/mjsunit/maglev/string-wrapper.js b/deps/v8/test/mjsunit/maglev/string-wrapper.js
index 0c088cde928..c84bcb4293b 100644
--- a/deps/v8/test/mjsunit/maglev/string-wrapper.js
+++ b/deps/v8/test/mjsunit/maglev/string-wrapper.js
@@ -17,7 +17,7 @@ assertTrue(s1 instanceof String);
assertEquals('object', typeof s1);
assertEquals('', s1.valueOf());
-assertTrue(isMaglevved(create1));
+assertMaglevved(create1);
function create2(v) {
return new String(v);
@@ -52,7 +52,7 @@ let s5 = create2(obj2);
assertEquals('object', typeof s5);
assertEquals('[object Object]', s5.valueOf());
-assertTrue(isMaglevved(create2));
+assertMaglevved(create2);
function create3() {
return new String('constant');
diff --git a/deps/v8/test/mjsunit/maglev/super-ic.js b/deps/v8/test/mjsunit/maglev/super-ic.js
index 6ac50687060..c009813ffcd 100644
--- a/deps/v8/test/mjsunit/maglev/super-ic.js
+++ b/deps/v8/test/mjsunit/maglev/super-ic.js
@@ -27,9 +27,9 @@ assertEquals(o.bar(), 42);
%OptimizeMaglevOnNextCall(o.bar);
assertEquals(o.bar(), 42);
-assertTrue(isMaglevved(o.bar));
+assertMaglevved(o.bar);
// This should deopt.
o.__proto__.__proto__ = new C();
assertEquals(o.bar(), 24);
-assertFalse(isMaglevved(o.bar));
+assertNotMaglevved(o.bar);
diff --git a/deps/v8/test/mjsunit/maglev/truncate-int32-many-uses.js b/deps/v8/test/mjsunit/maglev/truncate-int32-many-uses.js
index 1d8e4fec13a..6fc3460adba 100644
--- a/deps/v8/test/mjsunit/maglev/truncate-int32-many-uses.js
+++ b/deps/v8/test/mjsunit/maglev/truncate-int32-many-uses.js
@@ -22,4 +22,4 @@ foo(0, 1);
assertEquals(4294967296, foo(1073741823, 1073741823));
// Deopt because the addition overflows.
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/truncate-int32.js b/deps/v8/test/mjsunit/maglev/truncate-int32.js
index 7df9fe5ba63..3a73f1e8e76 100644
--- a/deps/v8/test/mjsunit/maglev/truncate-int32.js
+++ b/deps/v8/test/mjsunit/maglev/truncate-int32.js
@@ -21,4 +21,4 @@ assertEquals(10, foo(6, 2));
assertEquals(-1073741827, foo(1073741823, 1073741823));
// No deopts even if the addition overflows.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-abs.js b/deps/v8/test/mjsunit/maglev/typed-array-length-abs.js
index 64b9d079e8c..e66e54f58d0 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-abs.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-abs.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertEquals(100, v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertEquals(largeLength, v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-all-kinds.js b/deps/v8/test/mjsunit/maglev/typed-array-length-all-kinds.js
index 0ffa309eeec..ee1b81ef5b9 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-all-kinds.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-all-kinds.js
@@ -77,7 +77,7 @@ function test(f, size) {
%OptimizeMaglevOnNextCall(f);
assertEquals(size, f(size));
- assertTrue(isMaglevved(f));
+ assertMaglevved(f);
}
test(test_int8, 100);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-as-number-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-as-number-large.js
index 312bd8c273e..72fdcb7efdf 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-as-number-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-as-number-large.js
@@ -23,7 +23,7 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
const val1 = foo(100);
assertEquals(100, val1);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const val2 = foo(largeLength);
assertEquals(largeLength, val2);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-as-number.js b/deps/v8/test/mjsunit/maglev/typed-array-length-as-number.js
index 866ef0771a3..eac9a0b5547 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-as-number.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-as-number.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const val = foo(100);
assertEquals(100, val);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const a2 = foo(largeLength);
assertEquals(largeLength, a2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-bitwise.js b/deps/v8/test/mjsunit/maglev/typed-array-length-bitwise.js
index c1b7f214eeb..3a3b673cecf 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-bitwise.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-bitwise.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const a = foo(100);
assertEquals(100 | 0xff, a);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const a2 = foo(largeLength);
assertEquals(largeLength | 0xff, a2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-root.js b/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-root.js
index e735d1ba13b..727c81b6fe3 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-root.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-root.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertTrue(v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertTrue(v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-to-boolean-true.js b/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-to-boolean-true.js
index e58f7e50426..95393f37b8a 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-to-boolean-true.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-branch-if-to-boolean-true.js
@@ -21,12 +21,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertEquals(1, v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertEquals(1, v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1a.js b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1a.js
index 4d66c97b067..1e93b73afc8 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1a.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1a.js
@@ -19,4 +19,4 @@ assertEquals(3, foo(100));
%OptimizeMaglevOnNextCall(foo);
const val = foo(100);
assertEquals(3, val);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1b.js b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1b.js
index e5a89273e59..c6c17d3e533 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1b.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-1b.js
@@ -16,12 +16,12 @@ assertEquals(100, foo(100));
%OptimizeMaglevOnNextCall(foo);
const val1 = foo(100);
assertEquals(100, val1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
Object.defineProperty(Uint8Array.prototype, 'length',
{get: () => { return 3; }});
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
const val2 = foo(100);
assertEquals(3, val2);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2a.js b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2a.js
index 9e99a53062b..5dda9be29e9 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2a.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2a.js
@@ -18,4 +18,4 @@ assertEquals(3, foo(100));
%OptimizeMaglevOnNextCall(foo);
const val = foo(100);
assertEquals(3, val);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2b.js b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2b.js
index 71b79fc0cb7..b8c1d4f1ecc 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2b.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-custom-2b.js
@@ -16,11 +16,11 @@ assertEquals(100, foo(100));
%OptimizeMaglevOnNextCall(foo);
const val1 = foo(100);
assertEquals(100, val1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
Uint8Array.prototype.__proto__ = { get length() { return 3; }};
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
const val2 = foo(100);
assertEquals(3, val2);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-deopt-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-deopt-large.js
index de7f930c327..a5ca9e6e60a 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-deopt-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-deopt-large.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
function foo(size) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-detached-1.js b/deps/v8/test/mjsunit/maglev/typed-array-length-detached-1.js
index 07dadce1afc..b896a04adc1 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-detached-1.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-detached-1.js
@@ -15,9 +15,9 @@ foo(ta);
%OptimizeMaglevOnNextCall(foo);
assertEquals(128, foo(ta));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
ta.buffer.transfer();
assertEquals(0, foo(ta));
-assertFalse(isMaglevved(foo));
+assertNotMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-detached-2.js b/deps/v8/test/mjsunit/maglev/typed-array-length-detached-2.js
index 5f2dbe02cb9..b318773f433 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-detached-2.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-detached-2.js
@@ -17,9 +17,9 @@ foo(ta);
%OptimizeMaglevOnNextCall(foo);
assertEquals(128, foo(ta));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
ta.buffer.transfer();
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
assertEquals(0, foo(ta));
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-exception-phi.js b/deps/v8/test/mjsunit/maglev/typed-array-length-exception-phi.js
index 134f1d3abfe..a8e93e0b1fc 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-exception-phi.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-exception-phi.js
@@ -34,12 +34,12 @@ foo(100, false);
%OptimizeMaglevOnNextCall(foo);
assertEquals(100, foo(100, true));
assertEquals(42, foo(100, false));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
assertEquals(largeLength, foo(largeLength, true));
assertEquals(42, foo(largeLength, false));
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array-large.js
index bd4fc148621..1d95871956b 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array-large.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
// Use a top-level HOLEY_SMI_ELEMENTS array so that the test function doesn't
// get confused about unexpected ElementsKinds in configs which don't have
@@ -26,9 +26,9 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
const a1 = foo(100);
assertEquals(1, a1[100]);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const a2 = foo(largeLength);
assertEquals(1, a2[largeLength]);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array.js b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array.js
index 20108f4a462..845cfcad0e9 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-array.js
@@ -26,7 +26,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const a1 = foo(100);
assertEquals(1, a1[100]);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// If we create a large JSTypedArray (length doesn't fit in Int32), we'll deopt
// because the large length doesn't match the existing feedback for b[a.length].
@@ -34,5 +34,5 @@ if (%Is64Bit()) {
const largeLength = 8589934592;
const a2 = foo(largeLength);
assertEquals(1, a2[largeLength]);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array-large.js
index 93fd4d35b15..45c40fc3dae 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array-large.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --multi-mapped-mock-allocator
// Flags: --no-optimize-maglev-optimizes-to-turbofan
function foo(size) {
@@ -23,16 +23,16 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
const a1 = foo(100);
assertEquals(1, a1[100]);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const a2 = foo(largeLength);
assertEquals(1, a2[largeLength]);
// TODO(389019544): Fix the deopt loop and enable this:
- // assertTrue(isMaglevved(foo));
+ // assertMaglevved(foo);
// Once this is fixed also --no-optimize-maglev-optimizes-to-turbofan
// could be removed.
- assertFalse(isMaglevved(foo)); // This will fail when the issue is fixed.
+ assertNotMaglevved(foo); // This will fail when the issue is fixed.
} catch (e) {
// If alloating the TypedArray failed, we'll get a RangeError. Other
// errors are just normal test failures.
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array.js b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array.js
index 8c161909f3b..c3156fa737d 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-index-into-typed-array.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --multi-mapped-mock-allocator
function foo(size) {
let a = new Uint8Array(size);
@@ -18,7 +18,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const a1 = foo(100);
assertEquals(1, a1[100]);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// TODO(389019544): This might or might not fail once the deopt loop is fixed.
if (%Is64Bit()) {
@@ -26,7 +26,7 @@ if (%Is64Bit()) {
try {
const a2 = foo(largeLength);
assertEquals(1, a2[largeLength]);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
} catch (e) {
// If alloating the TypedArray failed, we'll get a RangeError. Other
// errors are just normal test failures.
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-iteration-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-iteration-large.js
index bf376c9256c..5fb6b1f534e 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-iteration-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-iteration-large.js
@@ -31,9 +31,9 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
const a1 = foo(100);
assertEquals(100, a1.length);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const a2 = foo(largeLength);
assertEquals(largeLength, a2.length);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-iteration.js b/deps/v8/test/mjsunit/maglev/typed-array-length-iteration.js
index 6614cd4a445..13c62b77a86 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-iteration.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-iteration.js
@@ -28,7 +28,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const a = foo(100);
assertEquals(100, a.length);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// If we create a large JSTypedArray (length doesn't fit in Smi), we'll deopt
// because the large length doesn't match the existing feedback for
@@ -37,5 +37,5 @@ if (%Is64Bit()) {
const largeLength = 8589934592;
const a2 = foo(largeLength);
assertEquals(largeLength, a2.length);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-parseint.js b/deps/v8/test/mjsunit/maglev/typed-array-length-parseint.js
index 207cbeba7d6..d23e66246e6 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-parseint.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-parseint.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertEquals(100, v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertEquals(largeLength, v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-phi.js b/deps/v8/test/mjsunit/maglev/typed-array-length-phi.js
index 4671b4d391a..d140aa60edb 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-phi.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-phi.js
@@ -25,12 +25,12 @@ foo(100, false);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100, true);
assertEquals(100, v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength, true);
assertEquals(largeLength, v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-rab-gsab.js b/deps/v8/test/mjsunit/maglev/typed-array-length-rab-gsab.js
index 0000b413901..80e1f84abf8 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-rab-gsab.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-rab-gsab.js
@@ -16,9 +16,9 @@ assertEquals(100, foo(ab));
%OptimizeMaglevOnNextCall(foo);
assertEquals(100, foo(ab));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
ab.resize(200);
assertEquals(200, foo(ab));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-store-as-uint8clamped.js b/deps/v8/test/mjsunit/maglev/typed-array-length-store-as-uint8clamped.js
index 984814c995a..5c8fe54a632 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-store-as-uint8clamped.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-store-as-uint8clamped.js
@@ -22,12 +22,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const a = foo(100);
assertEquals(100, a[0]);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const a2 = foo(largeLength);
assertEquals(255, a2[0]);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global-large.js
index 7241629db00..add710ae6e5 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global-large.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
var global = 0;
@@ -21,9 +21,9 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
foo(100);
assertEquals(100, global);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
foo(largeLength);
assertEquals(largeLength, global);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global.js b/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global.js
index fff3d3726ef..a0dd904a506 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-store-into-global.js
@@ -22,7 +22,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
foo(100);
assertEquals(100, global);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// If we create a large JSTypedArray (length doesn't fit in Smi), we'll deopt
// because the large length doesn't match the existing type for global.
@@ -30,5 +30,5 @@ if (%Is64Bit()) {
const largeLength = 8589934592;
foo(largeLength);
assertEquals(largeLength, global);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context-large.js
index a97a099221b..fc04ec36bff 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context-large.js
@@ -25,9 +25,9 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
foo(100);
assertEquals(100, scriptContextSlot);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
foo(largeLength);
assertEquals(largeLength, scriptContextSlot);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context.js b/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context.js
index 8dc0cef2197..b44ff29cc03 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-store-script-context.js
@@ -22,7 +22,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
foo(100);
assertEquals(100, scriptContextSlot);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
foo(100);
@@ -33,5 +33,5 @@ if (%Is64Bit()) {
const largeLength = 8589934592;
foo(largeLength);
assertEquals(largeLength, scriptContextSlot);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-to-boolean.js b/deps/v8/test/mjsunit/maglev/typed-array-length-to-boolean.js
index 46478937cdd..a19b6552b19 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-to-boolean.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-to-boolean.js
@@ -20,12 +20,12 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertFalse(v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// Also large JSTypedArray lengths are supported.
if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertFalse(v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-to-number-large.js b/deps/v8/test/mjsunit/maglev/typed-array-length-to-number-large.js
index 578a506bae2..c4524910272 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-to-number-large.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-to-number-large.js
@@ -23,9 +23,9 @@ if (%Is64Bit()) {
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertTrue(v1);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
const v2 = foo(largeLength);
assertTrue(v2);
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/typed-array-length-to-number.js b/deps/v8/test/mjsunit/maglev/typed-array-length-to-number.js
index 46e20801ccb..204b1be48c8 100644
--- a/deps/v8/test/mjsunit/maglev/typed-array-length-to-number.js
+++ b/deps/v8/test/mjsunit/maglev/typed-array-length-to-number.js
@@ -19,7 +19,7 @@ foo(100);
%OptimizeMaglevOnNextCall(foo);
const v1 = foo(100);
assertTrue(v1);
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
// But large JSTypedArray lengths cause a deopt, because the length doesn't
// match the feedback (SignedSmall).
@@ -27,5 +27,5 @@ if (%Is64Bit()) {
const largeLength = 8589934592;
const v2 = foo(largeLength);
assertTrue(v2);
- assertFalse(isMaglevved(foo));
+ assertNotMaglevved(foo);
}
diff --git a/deps/v8/test/mjsunit/maglev/uint8-clamped-store-undefined.js b/deps/v8/test/mjsunit/maglev/uint8-clamped-store-undefined.js
index df93c4f4570..a12c7216188 100644
--- a/deps/v8/test/mjsunit/maglev/uint8-clamped-store-undefined.js
+++ b/deps/v8/test/mjsunit/maglev/uint8-clamped-store-undefined.js
@@ -25,4 +25,4 @@ foo(ta, 0, undefined);
assertEquals(0, ta[0]);
// Without the fix this would deopt on every call, so the function would no
// longer be Maglev-optimized here.
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/undefined-or-null-branch.js b/deps/v8/test/mjsunit/maglev/undefined-or-null-branch.js
index c1da43b1fcb..cc4833c2c8c 100644
--- a/deps/v8/test/mjsunit/maglev/undefined-or-null-branch.js
+++ b/deps/v8/test/mjsunit/maglev/undefined-or-null-branch.js
@@ -16,4 +16,4 @@ assertEquals(1, foo(1));
assertEquals(10, foo(undefined));
assertEquals(10, foo(null));
assertEquals(1, foo(1));
-assertTrue(isMaglevved(foo));
+assertMaglevved(foo);
diff --git a/deps/v8/test/mjsunit/maglev/unstable-map-transition.js b/deps/v8/test/mjsunit/maglev/unstable-map-transition.js
index 0db173f210e..752ce7d3d2a 100644
--- a/deps/v8/test/mjsunit/maglev/unstable-map-transition.js
+++ b/deps/v8/test/mjsunit/maglev/unstable-map-transition.js
@@ -13,5 +13,5 @@
foo({});
%OptimizeMaglevOnNextCall(foo);
foo({});
- assertTrue(isMaglevved(foo));
+ assertMaglevved(foo);
})();
diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js
index 8f04540166b..6f4de2b61fa 100644
--- a/deps/v8/test/mjsunit/mjsunit.js
+++ b/deps/v8/test/mjsunit/mjsunit.js
@@ -162,6 +162,8 @@ var assertUnreachable;
// Only works with --allow-natives-syntax.
var assertOptimized;
var assertUnoptimized;
+var assertMaglevved;
+var assertNotMaglevved;
// Assert that a string contains another expected substring.
var assertContains;
@@ -205,7 +207,7 @@ var V8OptimizationStatus = {
kTopmostFrameIsMaglev: 1 << 18,
kOptimizeOnNextCallOptimizesToMaglev: 1 << 19,
kOptimizeMaglevOptimizesToTurbofan: 1 << 20,
- kMarkedForMagkevOptimization: 1 << 21,
+ kMarkedForMaglevOptimization: 1 << 21,
kMarkedForConcurrentMaglevOptimization: 1 << 22,
};
@@ -788,9 +790,10 @@ var prettyPrinted;
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0, name_opt);
if (skip_if_maybe_deopted &&
(opt_status & V8OptimizationStatus.kMaybeDeopted) !== 0) {
- // When --deopt-every-n-times flag is specified it's no longer guaranteed
- // that particular function is still deoptimized, so keep running the test
- // to stress test the deoptimizer.
+ // When --deopt-every-n-times flag, GC stress flags, or similar are
+ // specified, it's no longer guaranteed that a particular function is
+ // still deoptimized, so keep running the test to stress test the
+ // deoptimizer.
return;
}
var is_optimized = (opt_status & V8OptimizationStatus.kOptimized) !== 0;
@@ -816,6 +819,33 @@ var prettyPrinted;
assertFalse(is_optimized, 'should not be optimized: ' + name_opt);
}
+ assertNotMaglevved = function assertNotMaglevved(
+ fun, name_opt, skip_if_maybe_deopted = true) {
+ let opt_status = OptimizationStatus(fun);
+ name_opt = name_opt ?? fun.name;
+ assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0, name_opt);
+ if (skip_if_maybe_deopted &&
+ (opt_status & V8OptimizationStatus.kMaybeDeopted) !== 0) {
+ // When --deopt-every-n-times flag, GC stress flags, or similar are
+ // specified, it's no longer guaranteed that a particular function is
+ // still deoptimized, so keep running the test to stress test the
+ // deoptimizer.
+ return;
+ }
+ if (opt_status &
+ V8OptimizationStatus.kOptimizeMaglevOptimizesToTurbofan) {
+ // In some cases, Turbofan actually emits more generic code than Maglev
+ // (for instance, allowing Oddballs where Maglev only allows HeapNumbers),
+ // and assertNotMaglevved with --optimize-maglev-optimizes-to-turbofan
+ // will fail. In those cases, we still want this assert to succeed and the
+ // test to continue.
+ return;
+ }
+ let is_maglevved = (opt_status & V8OptimizationStatus.kOptimized) !== 0
+ && (opt_status & V8OptimizationStatus.kMaglevved) !== 0;
+ assertFalse(is_maglevved, 'should not be maglevved: ' + name_opt);
+ }
+
assertOptimized = function assertOptimized(
fun, name_opt, skip_if_maybe_deopted = true) {
var opt_status = OptimizationStatus(fun);
@@ -826,18 +856,20 @@ var prettyPrinted;
print("Warning: Test uses assertOptimized in Lite mode, skipping test.");
quit(0);
}
- // Tests that use assertOptimized() do not make sense if --no-turbofan
- // option is provided. Such tests must add --turbofan to flags comment.
+ // Tests that use assertOptimized() do not make sense if no optimizing
+ // compilers are enabled. Such tests must add --turbofan / --maglev to flags
+ // comment.
assertFalse((opt_status & V8OptimizationStatus.kNeverOptimize) !== 0,
- "test does not make sense with --no-turbofan");
+ "test does not make sense with --no-turbofan --no-maglev");
assertTrue(
(opt_status & V8OptimizationStatus.kIsFunction) !== 0,
'should be a function: ' + name_opt);
if (skip_if_maybe_deopted &&
(opt_status & V8OptimizationStatus.kMaybeDeopted) !== 0) {
- // When --deopt-every-n-times flag is specified it's no longer guaranteed
- // that particular function is still optimized, so keep running the test
- // to stress test the deoptimizer.
+ // When --deopt-every-n-times flag, GC stress flags, or similar are
+ // specified, it's no longer guaranteed that a particular function is
+ // still optimized, so keep running the test to stress test the
+ // deoptimizer.
return;
}
if ((opt_status &
@@ -852,6 +884,44 @@ var prettyPrinted;
'should be optimized: ' + name_opt);
}
+ assertMaglevved = function assertMaglevved(
+ fun, name_opt, skip_if_maybe_deopted = true) {
+ let opt_status = OptimizationStatus(fun);
+ name_opt = name_opt ?? fun.name;
+ // Tests that use assertMaglevved() do not make sense for Lite mode where
+ // optimization is always disabled, explicitly exit the test with a warning.
+ if (opt_status & V8OptimizationStatus.kLiteMode) {
+ print("Warning: Test uses assertMaglevved in Lite mode, skipping test.");
+ quit(0);
+ }
+ // Tests that use assertMaglevved() do not make sense if no optimizing
+ // compilers are enabled. Such tests must add --turbofan / --maglev to flags
+ // comment.
+ assertFalse((opt_status & V8OptimizationStatus.kNeverOptimize) !== 0,
+ "test does not make sense with --no-turbofan --no-maglev");
+ assertTrue(
+ (opt_status & V8OptimizationStatus.kIsFunction) !== 0,
+ 'should be a function: ' + name_opt);
+ if (skip_if_maybe_deopted &&
+ (opt_status & V8OptimizationStatus.kMaybeDeopted) !== 0) {
+ // When --deopt-every-n-times flag, GC stress flags, or similar are
+ // specified, it's no longer guaranteed that a particular function is
+ // still optimized, so keep running the test to stress test the
+ // deoptimizer.
+ return;
+ }
+ if ((opt_status &
+ V8OptimizationStatus.kOptimizeMaglevOptimizesToTurbofan) !== 0) {
+ // When --optimize-maglev-optimizes-to-turbofan is used it's no longer
+ // guaranteed that a particular function stays optimized the same way
+ // as with Maglev.
+ return;
+ }
+ let is_maglevved = (opt_status & V8OptimizationStatus.kOptimized) !== 0
+ && (opt_status & V8OptimizationStatus.kMaglevved) !== 0;
+ assertTrue(is_maglevved, 'should be maglevved: ' + name_opt);
+ }
+
isNeverOptimizeLiteMode = function isNeverOptimizeLiteMode() {
var opt_status = OptimizationStatus(undefined, "");
return (opt_status & V8OptimizationStatus.kLiteMode) !== 0;
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index aaa65a3666f..af6517a6a8f 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -202,12 +202,16 @@
'regress/regress-crbug-808192': [PASS, SLOW, NO_VARIANTS, ['arch not in (ia32, x64)', SKIP], ['tsan', SKIP]],
'regress/regress-crbug-918301': [PASS, SLOW, NO_VARIANTS, ['mode != release or dcheck_always_on', SKIP], ['(arch == arm or arch == arm64) and simulator_run', SKIP]],
'regress/regress-crbug-1276923': [PASS, SLOW],
+ # Builds a chain of 80000 functions, which takes minutes with dchecks.
+ 'regress/regress-crbug-388320179': [PASS, ['mode != release', SKIP]],
'regress/regress-390568195': [PASS, SLOW, NO_VARIANTS, ['mode != release or dcheck_always_on', SKIP], ['arch != x64', SKIP]],
'regress/regress-447613219': [PASS, SLOW],
'regress/regress-494583765' : [PASS, SLOW],
'regress/regress-7558019': [PASS, SLOW],
'regress/regress-499721612': [PASS, SLOW],
'regress/regress-498010834': [PASS, SLOW],
+ 'regress/regress-506499280-extended': [PASS, SLOW],
+ 'regress/regress-558568713': [PASS, SLOW, NO_VARIANTS],
'regress/regress-rab-proto-oob': [PASS, SLOW, ['tsan', SKIP]],
'regress/regress-crbug-503557995-b': [PASS, ['mode != release or simulator_run', SKIP]],
'regress/wasm/regress-810973': [PASS, SLOW],
@@ -265,6 +269,7 @@
'regress/regress-1034322': [PASS, HEAVY, NO_VARIANTS, ['mode != release', SKIP]],
'regress/regress-1320641': [PASS, HEAVY],
'regress/regress-1447343': [PASS, HEAVY],
+ 'regress/wasm/regress-523591366': [PASS, HEAVY],
'wasm/grow-huge-memory': [PASS, HEAVY],
'wasm/grow-huge-memory-resizable-buffer': [PASS, HEAVY],
'wasm/huge-memory': [PASS, HEAVY],
@@ -909,7 +914,7 @@
'wasm/memory-control': [SKIP],
'regress/wasm/regress-493307331': [SKIP],
- # --experimental-wasm-acquire-release
+ # --wasm-acquire-release
'wasm/acq-rel-fence': [SKIP],
'wasm/acq-rel-load-and-store': [SKIP],
'wasm/acq-rel-rmw-operations': [SKIP],
@@ -1069,6 +1074,7 @@
'regress/wasm/regress-521064735': [SKIP],
'regress/wasm/regress-524830496': [SKIP],
'regress/wasm/regress-536581698': [SKIP],
+ 'regress/wasm/regress-565565747': [SKIP],
'wasm/shared-everything/*': [SKIP],
'wasm/subtyping-invalid': [SKIP],
@@ -1145,7 +1151,7 @@
'regress/wasm/regress-simd-520944504': [SKIP],
'wasm/wide-arithmetic': [SKIP],
- # --experimental-wasm-imported-strings-utf8
+ # --wasm-imported-strings-utf8
'regress/wasm/regress-525472599': [SKIP],
# --wasm-deopt
@@ -1303,6 +1309,12 @@
['arch != arm64', {
'wasm/half-shuffles': [SKIP],
'wasm/redundant-shuffle-lanes': [SKIP],
+ 'wasm/interleaved-loads': [SKIP],
+ 'regress/wasm/regress-simd-467479137': [SKIP],
+ 'regress/wasm/regress-simd-549328680': [SKIP],
+ 'regress/wasm/regress-simd-549328680-2': [SKIP],
+ 'regress/wasm/regress-simd-511097641': [SKIP],
+ 'regress/wasm/regress-simd-525600038': [SKIP],
}],
##############################################################################
@@ -1321,32 +1333,10 @@
'regexp-tier-up-multiple': [SKIP],
'regress/regress-996234': [SKIP],
- # These tests rely on TurboFan being enabled.
+ # These tests rely on TurboFan being enabled and suppress flag contradiction
+ # checks (--flag-processing-mode=ignore-contradictions or --fuzzing).
'ensure-growing-store-learns': [SKIP],
- 'compiler/call-with-arraylike-or-spread*': [SKIP],
- 'compiler/fast-api-calls': [SKIP],
- 'compiler/fast-api-attributes': [SKIP],
- 'compiler/fast-api-interface-types': [SKIP],
- 'compiler/fast-api-deopt': [SKIP],
- 'regress/regress-505551322': [SKIP],
- 'regress/regress-508672637': [SKIP],
- 'regress/regress-fast-api-uint64-negative': [SKIP],
- 'compiler/regress-crbug-1201011': [SKIP],
- 'compiler/regress-crbug-1201057': [SKIP],
- 'compiler/regress-crbug-1201082': [SKIP],
- 'compiler/regress-331909453': [SKIP],
- 'compiler/regress-crbug-1457532': [SKIP],
'regress/regress-390675705': [SKIP],
- 'regress/regress-395028748': [SKIP],
- 'regress/regress-424627229': [SKIP],
- 'regress/regress-438321229': [SKIP],
-
- 'wasm/fast-api-calls-with-wellknown-imports*': [SKIP],
- 'regress/wasm/regress-368086282': [SKIP],
- 'regress/wasm/regress-438770394': [SKIP],
-
- 'maglev/extras-cped': [SKIP],
- 'turboshaft/extras-cped': [SKIP],
# These tests check that we can trace the compiler.
'tools/compiler-trace-flags': [SKIP],
@@ -1403,6 +1393,7 @@
'tzoffset-transition-moscow': [PASS,FAIL],
'tzoffset-transition-new-york': [PASS,FAIL],
'tzoffset-seoul': [PASS,FAIL],
+ 'tzoffset-fractional-los-angeles': [PASS,FAIL],
# i18n is required for Intl
'regress/regress-crbug-1052647': [PASS,FAIL],
@@ -1464,6 +1455,7 @@
'regress/regress-1320641': [SKIP],
'regress/regress-354626177': [SKIP],
'regress/wasm/regress-398439335': [SKIP],
+ 'regress/wasm/regress-523591366': [SKIP],
'turbolev/regress-488090094': [SKIP],
'turbolev/dataview-deopt-oob': [SKIP],
'maglev/regress-498816446-3': [SKIP],
@@ -1933,6 +1925,7 @@
'tzoffset-transition-new-york': [SKIP],
'tzoffset-transition-new-york-noi18n': [SKIP],
'tzoffset-seoul': [SKIP],
+ 'tzoffset-fractional-los-angeles': [SKIP],
'tzoffset-seoul-noi18n': [SKIP],
# Suspect to stress other tests when run in background.
@@ -1961,6 +1954,7 @@
'tzoffset-transition-new-york': [SKIP],
'tzoffset-transition-new-york-noi18n': [SKIP],
'tzoffset-seoul': [SKIP],
+ 'tzoffset-fractional-los-angeles': [SKIP],
'tzoffset-seoul-noi18n': [SKIP],
# Flaky OOM:
'regress/regress-748069': [SKIP],
@@ -2137,6 +2131,8 @@
# Too slow.
'wasm/futex': [SKIP],
+ # Builds a chain of 80000 functions; times out on the tsan bot.
+ 'regress/regress-crbug-388320179': [SKIP],
# https://crbug.com/496520250
'maglev/regress-494492520': [SKIP],
@@ -2213,6 +2209,10 @@
# https://crbug.com/556584687
'turboshaft/regress-508265328-*': [SKIP],
+
+ # https://crbug.com/564743658
+ # Flag implications override the flag setting in the test.
+ 'wasm/multiple-code-spaces': [SKIP],
}], # num_fuzzer
##############################################################################
@@ -2496,29 +2496,9 @@
##############################################################################
['variant == nooptimization', {
-
- # Tests that depend on optimization (beyond doing assertOptimized).
+ # Uses --flag-processing-mode=ignore-contradictions, which suppresses the
+ # flag contradiction error with --turbofan.
'ensure-growing-store-learns': [SKIP],
- 'regress/regress-1049982-1': [SKIP],
- 'regress/regress-1049982-2': [SKIP],
-
- 'maglev/extras-cped': [SKIP],
- 'turboshaft/extras-cped': [SKIP],
-
- # Wasm serialization relies on TurboFan to be available, hence does not work
- # in the 'nooptimization' variant.
- 'regress/wasm/regress-7785': [SKIP],
-
- # Tests that require wasm tier up.
- 'wasm/recognize-imports': [SKIP],
- 'wasm/speculative-inlining': [SKIP],
- 'wasm/wasm-dynamic-tiering': [SKIP],
- 'regress/wasm/regress-1179065': [SKIP],
- 'regress/wasm/regress-334687959': [SKIP],
-
- # These tests require Turbolev (--turbofan) which nooptimization disables.
- 'wasm/wasm-wrapper-inlining-turbolev': [SKIP],
- 'wasm/wrapper-inlining-lazy-deopt-turbolev': [SKIP],
}], # variant == nooptimization
##############################################################################
@@ -2573,9 +2553,22 @@
##############################################################################
['system != linux', {
- # Multi-mapped mock allocator is only available on Linux.
+ # Multi-mapped mock allocator is only available on Linux. These tests allocate
+ # >2 GiB ArrayBuffer backing stores (exceeding PartitionAlloc's max allocation
+ # size) and access elements beyond the single OS page allocated by
+ # --mock-arraybuffer-allocator.
+ 'maglev/regress-525732296': [SKIP],
+ 'maglev/typed-array-length-index-into-typed-array': [SKIP],
+ 'maglev/typed-array-length-index-into-typed-array-large': [SKIP],
+ 'regress/regress-499527555': [SKIP],
+ 'regress/regress-499527555-2': [SKIP],
+ 'regress/regress-509312809': [SKIP],
'regress/regress-crbug-1041232': [SKIP],
'regress/regress-crbug-1104608': [SKIP],
+ 'turbolev/dataview-deopt-oob': [SKIP],
+ 'turbolev/regress-488090094': [SKIP],
+ 'turbolev/typed-array-length-index-into-typed-array': [SKIP],
+ 'turbolev/typed-array-length-index-into-typed-array-large': [SKIP],
# WebAssembly memory control is only implemented on Linux so far.
'wasm/memory-control': [SKIP],
@@ -2949,6 +2942,7 @@
'regress/wasm/regress-483269968': [SKIP],
'regress/wasm/regress-543901836': [SKIP],
'regress/wasm/regress-560536735': [SKIP],
+ 'regress/wasm/regress-561660149': [SKIP],
'compiler/regress-347724915': [SKIP],
'regress/regress-crbug-418520151': [SKIP],
'regress/regress-535000102': [SKIP],
@@ -3281,9 +3275,24 @@
['sandbox_hardware_support', {
# Skip tests for unsupported features. See https://crbug.com/428674890.
- # Multi-mapped mock allocator is not currently supported.
+ # Multi-mapped mock allocator is not currently supported with hardware
+ # sandboxing (mremap overwrites the sandbox pkey on the remapped pages).
+ # These tests allocate >2 GiB ArrayBuffer backing stores (exceeding
+ # PartitionAlloc's max allocation size) and access elements beyond the single
+ # OS page allocated by --mock-arraybuffer-allocator.
+ 'maglev/regress-525732296': [SKIP],
+ 'maglev/typed-array-length-index-into-typed-array': [SKIP],
+ 'maglev/typed-array-length-index-into-typed-array-large': [SKIP],
+ 'regress/regress-499527555': [SKIP],
+ 'regress/regress-499527555-2': [SKIP],
+ 'regress/regress-509312809': [SKIP],
'regress/regress-crbug-1041232': [SKIP],
+ 'regress/regress-crbug-1104608': [SKIP],
'regress/regress-crbug-1209152': [SKIP],
+ 'turbolev/dataview-deopt-oob': [SKIP],
+ 'turbolev/regress-488090094': [SKIP],
+ 'turbolev/typed-array-length-index-into-typed-array': [SKIP],
+ 'turbolev/typed-array-length-index-into-typed-array-large': [SKIP],
# Wasm code coverage is not currently supported.
'regress/wasm/regress-488943662': [SKIP],
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-arrow-function.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-arrow-function.js
index 3eb4112e8da..50605eae7c1 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-arrow-function.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-arrow-function.js
@@ -55,7 +55,7 @@ assert_test_arrow_function(test_arrow_function());
%OptimizeMaglevOnNextCall(test_arrow_function);
assert_test_arrow_function(test_arrow_function());
assertOptimized(test_arrow_function);
-assertTrue(isMaglevved(test_arrow_function));
+assertMaglevved(test_arrow_function);
assert_test_arrow_function(test_arrow_function());
%OptimizeFunctionOnNextCall(test_arrow_function);
assert_test_arrow_function(test_arrow_function());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-assign-key-multiple-times.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-assign-key-multiple-times.js
index 2ac89796297..3187d06eb16 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-assign-key-multiple-times.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-assign-key-multiple-times.js
@@ -42,7 +42,7 @@ assert_test_assign_key_multiple_times(test_assign_key_multiple_times());
%OptimizeMaglevOnNextCall(test_assign_key_multiple_times);
assert_test_assign_key_multiple_times(test_assign_key_multiple_times());
assertOptimized(test_assign_key_multiple_times);
-assertTrue(isMaglevved(test_assign_key_multiple_times));
+assertMaglevved(test_assign_key_multiple_times);
assert_test_assign_key_multiple_times(test_assign_key_multiple_times());
%OptimizeFunctionOnNextCall(test_assign_key_multiple_times);
assert_test_assign_key_multiple_times(test_assign_key_multiple_times());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-basic.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-basic.js
index 1486c8b44e8..b96d122cd1d 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-basic.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-basic.js
@@ -46,7 +46,7 @@ assert_test_basic_optimization(test_basic_optimization());
%OptimizeMaglevOnNextCall(test_basic_optimization);
assert_test_basic_optimization(test_basic_optimization());
assertOptimized(test_basic_optimization);
-assertTrue(isMaglevved(test_basic_optimization));
+assertMaglevved(test_basic_optimization);
assert_test_basic_optimization(test_basic_optimization());
%OptimizeFunctionOnNextCall(test_basic_optimization);
assert_test_basic_optimization(test_basic_optimization());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-before-after.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-before-after.js
index e57e04f6ba9..ef5a1156db9 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-before-after.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-before-after.js
@@ -44,7 +44,7 @@ assert_test_before_after(test_before_after());
%OptimizeMaglevOnNextCall(test_before_after);
assert_test_before_after(test_before_after());
assertOptimized(test_before_after);
-assertTrue(isMaglevved(test_before_after));
+assertMaglevved(test_before_after);
assert_test_before_after(test_before_after());
%OptimizeFunctionOnNextCall(test_before_after);
assert_test_before_after(test_before_after());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-class-fast-path.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-class-fast-path.js
index 725e0755d42..ec03019b20e 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-class-fast-path.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-class-fast-path.js
@@ -50,7 +50,7 @@ assert_test_class_fast_path(test_class_fast_path());
%OptimizeMaglevOnNextCall(test_class_fast_path);
assert_test_class_fast_path(test_class_fast_path());
assertOptimized(test_class_fast_path);
-assertTrue(isMaglevved(test_class_fast_path));
+assertMaglevved(test_class_fast_path);
assert_test_class_fast_path(test_class_fast_path());
%OptimizeFunctionOnNextCall(test_class_fast_path);
assert_test_class_fast_path(test_class_fast_path());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-computed.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-computed.js
index 4b5b82ccccb..bd673f46847 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-computed.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-computed.js
@@ -32,7 +32,7 @@ assert_test_computed_property(test_computed_property());
%OptimizeMaglevOnNextCall(test_computed_property);
assert_test_computed_property(test_computed_property());
assertOptimized(test_computed_property);
-assertTrue(isMaglevved(test_computed_property));
+assertMaglevved(test_computed_property);
assert_test_computed_property(test_computed_property());
%OptimizeFunctionOnNextCall(test_computed_property);
assert_test_computed_property(test_computed_property());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-constructor.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-constructor.js
index 356db95884a..a7779ae23d8 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-constructor.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-constructor.js
@@ -33,7 +33,7 @@ assert_test_constructor_assignment(test_constructor_assignment());
%OptimizeMaglevOnNextCall(test_constructor_assignment);
assert_test_constructor_assignment(test_constructor_assignment());
assertOptimized(test_constructor_assignment);
-assertTrue(isMaglevved(test_constructor_assignment));
+assertMaglevved(test_constructor_assignment);
assert_test_constructor_assignment(test_constructor_assignment());
%OptimizeFunctionOnNextCall(test_constructor_assignment);
assert_test_constructor_assignment(test_constructor_assignment());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-left-most-var.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-left-most-var.js
index 20d3b76f55d..6ee439708a5 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-left-most-var.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-left-most-var.js
@@ -39,7 +39,7 @@ assert_test_different_left_most_var(test_different_left_most_var());
%OptimizeMaglevOnNextCall(test_different_left_most_var);
assert_test_different_left_most_var(test_different_left_most_var());
assertOptimized(test_different_left_most_var);
-assertTrue(isMaglevved(test_different_left_most_var));
+assertMaglevved(test_different_left_most_var);
assert_test_different_left_most_var(test_different_left_most_var());
%OptimizeFunctionOnNextCall(test_different_left_most_var);
assert_test_different_left_most_var(test_different_left_most_var());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-objects.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-objects.js
index 9100877e7c5..4a73605be8b 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-objects.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-different-objects.js
@@ -36,7 +36,7 @@ assert_test_different_objects(test_different_objects());
%OptimizeMaglevOnNextCall(test_different_objects);
assert_test_different_objects(test_different_objects());
assertOptimized(test_different_objects);
-assertTrue(isMaglevved(test_different_objects));
+assertMaglevved(test_different_objects);
assert_test_different_objects(test_different_objects());
%OptimizeFunctionOnNextCall(test_different_objects);
assert_test_different_objects(test_different_objects());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-duplicate.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-duplicate.js
index 21f4100d76c..471210cea4d 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-duplicate.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-duplicate.js
@@ -35,7 +35,7 @@ assert_test_duplicate_properties(test_duplicate_properties());
%OptimizeMaglevOnNextCall(test_duplicate_properties);
assert_test_duplicate_properties(test_duplicate_properties());
assertOptimized(test_duplicate_properties);
-assertTrue(isMaglevved(test_duplicate_properties));
+assertMaglevved(test_duplicate_properties);
assert_test_duplicate_properties(test_duplicate_properties());
%OptimizeFunctionOnNextCall(test_duplicate_properties);
assert_test_duplicate_properties(test_duplicate_properties());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-eval-return-last-set-property.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-eval-return-last-set-property.js
index 474ca0fe313..c11d2b826e3 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-eval-return-last-set-property.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-eval-return-last-set-property.js
@@ -32,7 +32,7 @@ assert_test_eval_return_last_set_property(test_eval_return_last_set_property());
%OptimizeMaglevOnNextCall(test_eval_return_last_set_property);
assert_test_eval_return_last_set_property(test_eval_return_last_set_property());
assertOptimized(test_eval_return_last_set_property);
-assertTrue(isMaglevved(test_eval_return_last_set_property));
+assertMaglevved(test_eval_return_last_set_property);
assert_test_eval_return_last_set_property(test_eval_return_last_set_property());
%OptimizeFunctionOnNextCall(test_eval_return_last_set_property);
assert_test_eval_return_last_set_property(test_eval_return_last_set_property());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-feedback-vector-side-effect.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-feedback-vector-side-effect.js
index 4f025b9f13a..84ce0f8649d 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-feedback-vector-side-effect.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-feedback-vector-side-effect.js
@@ -42,7 +42,7 @@ assert_test_feedback_vector_side_effect(test_feedback_vector_side_effect());
%OptimizeMaglevOnNextCall(test_feedback_vector_side_effect);
assert_test_feedback_vector_side_effect(test_feedback_vector_side_effect());
assertOptimized(test_feedback_vector_side_effect);
-assertTrue(isMaglevved(test_feedback_vector_side_effect));
+assertMaglevved(test_feedback_vector_side_effect);
assert_test_feedback_vector_side_effect(test_feedback_vector_side_effect());
%OptimizeFunctionOnNextCall(test_feedback_vector_side_effect);
assert_test_feedback_vector_side_effect(test_feedback_vector_side_effect());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects-strict.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects-strict.js
index 075f371c56e..87b87c902ac 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects-strict.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects-strict.js
@@ -41,7 +41,7 @@ assert_test_frozen_objects(test_frozen_objects());
%OptimizeMaglevOnNextCall(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
assertOptimized(test_frozen_objects);
-assertTrue(isMaglevved(test_frozen_objects));
+assertMaglevved(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
%OptimizeFunctionOnNextCall(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects.js
index 031520ac2f1..38faf00d6c5 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-frozen-objects.js
@@ -38,7 +38,7 @@ assert_test_frozen_objects(test_frozen_objects());
%OptimizeMaglevOnNextCall(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
assertOptimized(test_frozen_objects);
-assertTrue(isMaglevved(test_frozen_objects));
+assertMaglevved(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
%OptimizeFunctionOnNextCall(test_frozen_objects);
assert_test_frozen_objects(test_frozen_objects());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-function-fast-path.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-function-fast-path.js
index 383017c5ca5..5e9d1708e7c 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-function-fast-path.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-function-fast-path.js
@@ -49,7 +49,7 @@ assert_test_function_fast_path(test_function_fast_path());
%OptimizeMaglevOnNextCall(test_function_fast_path);
assert_test_function_fast_path(test_function_fast_path());
assertOptimized(test_function_fast_path);
-assertTrue(isMaglevved(test_function_fast_path));
+assertMaglevved(test_function_fast_path);
assert_test_function_fast_path(test_function_fast_path());
%OptimizeFunctionOnNextCall(test_function_fast_path);
assert_test_function_fast_path(test_function_fast_path());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-functions.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-functions.js
index a9b101dce23..6273200fcc1 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-functions.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-functions.js
@@ -36,7 +36,7 @@ assert_test_functions_optimization(test_functions_optimization());
%OptimizeMaglevOnNextCall(test_functions_optimization);
assert_test_functions_optimization(test_functions_optimization());
assertOptimized(test_functions_optimization);
-assertTrue(isMaglevved(test_functions_optimization));
+assertMaglevved(test_functions_optimization);
assert_test_functions_optimization(test_functions_optimization());
%OptimizeFunctionOnNextCall(test_functions_optimization);
assert_test_functions_optimization(test_functions_optimization());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptor.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptor.js
index cc9d520cc16..92e0fb7bdbf 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptor.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptor.js
@@ -32,7 +32,7 @@ assert_test_getOwnPropertyDescriptor(test_getOwnPropertyDescriptor());
%OptimizeMaglevOnNextCall(test_getOwnPropertyDescriptor);
assert_test_getOwnPropertyDescriptor(test_getOwnPropertyDescriptor());
assertOptimized(test_getOwnPropertyDescriptor);
-assertTrue(isMaglevved(test_getOwnPropertyDescriptor));
+assertMaglevved(test_getOwnPropertyDescriptor);
assert_test_getOwnPropertyDescriptor(test_getOwnPropertyDescriptor());
%OptimizeFunctionOnNextCall(test_getOwnPropertyDescriptor);
assert_test_getOwnPropertyDescriptor(test_getOwnPropertyDescriptor());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptors.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptors.js
index 3a1c19ea155..3680639c1f5 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptors.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-get-own-property-descriptors.js
@@ -37,7 +37,7 @@ assert_test_getOwnPropertyDescriptors(test_getOwnPropertyDescriptors());
%OptimizeMaglevOnNextCall(test_getOwnPropertyDescriptors);
assert_test_getOwnPropertyDescriptors(test_getOwnPropertyDescriptors());
assertOptimized(test_getOwnPropertyDescriptors);
-assertTrue(isMaglevved(test_getOwnPropertyDescriptors));
+assertMaglevved(test_getOwnPropertyDescriptors);
assert_test_getOwnPropertyDescriptors(test_getOwnPropertyDescriptors());
%OptimizeFunctionOnNextCall(test_getOwnPropertyDescriptors);
assert_test_getOwnPropertyDescriptors(test_getOwnPropertyDescriptors());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-global-proxy.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-global-proxy.js
index a1efb109e5a..a391fb5ad4e 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-global-proxy.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-global-proxy.js
@@ -34,7 +34,7 @@ function run(){
%OptimizeMaglevOnNextCall(test_global_proxy);
assert_test_global_proxy(test_global_proxy());
assertOptimized(test_global_proxy);
- assertTrue(isMaglevved(test_global_proxy));
+ assertMaglevved(test_global_proxy);
assert_test_global_proxy(test_global_proxy());
%OptimizeFunctionOnNextCall(test_global_proxy);
assert_test_global_proxy(test_global_proxy());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-prototype-keys.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-prototype-keys.js
index c4b9fc12bab..e4e292bd73f 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-prototype-keys.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-prototype-keys.js
@@ -52,7 +52,7 @@ assert_test_has_prototype_keys(test_has_prototype_keys());
%OptimizeMaglevOnNextCall(test_has_prototype_keys);
assert_test_has_prototype_keys(test_has_prototype_keys());
assertOptimized(test_has_prototype_keys);
-assertTrue(isMaglevved(test_has_prototype_keys));
+assertMaglevved(test_has_prototype_keys);
assert_test_has_prototype_keys(test_has_prototype_keys());
%OptimizeFunctionOnNextCall(test_has_prototype_keys);
assert_test_has_prototype_keys(test_has_prototype_keys());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-setters.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-setters.js
index bd30488f28e..1b4984a44ff 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-setters.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-has-setters.js
@@ -52,7 +52,7 @@ assert_test_has_setters(test_has_setters());
%OptimizeMaglevOnNextCall(test_has_setters);
assert_test_has_setters(test_has_setters());
assertOptimized(test_has_setters);
-assertTrue(isMaglevved(test_has_setters));
+assertMaglevved(test_has_setters);
assert_test_has_setters(test_has_setters());
%OptimizeFunctionOnNextCall(test_has_setters);
assert_test_has_setters(test_has_setters());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-ignore-chain-descriptors.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-ignore-chain-descriptors.js
index fff34c103cf..b1940b65ac4 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-ignore-chain-descriptors.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-ignore-chain-descriptors.js
@@ -42,7 +42,7 @@ function run(){
%OptimizeMaglevOnNextCall(test_ignore_chain_descriptors);
assert_test_ignore_chain_descriptors(test_ignore_chain_descriptors());
assertOptimized(test_ignore_chain_descriptors);
- assertTrue(isMaglevved(test_ignore_chain_descriptors));
+ assertMaglevved(test_ignore_chain_descriptors);
assert_test_ignore_chain_descriptors(test_ignore_chain_descriptors());
%OptimizeFunctionOnNextCall(test_ignore_chain_descriptors);
assert_test_ignore_chain_descriptors(test_ignore_chain_descriptors());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-iife.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-iife.js
index 428df085827..c5c2008c0e4 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-iife.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-iife.js
@@ -40,7 +40,7 @@ assert_test_iife(test_iife());
%OptimizeMaglevOnNextCall(test_iife);
assert_test_iife(test_iife());
assertOptimized(test_iife);
-assertTrue(isMaglevved(test_iife));
+assertMaglevved(test_iife);
assert_test_iife(test_iife());
%OptimizeFunctionOnNextCall(test_iife);
assert_test_iife(test_iife());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-interleaved.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-interleaved.js
index aed08d6b6cc..fe6cd8bf8f4 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-interleaved.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-interleaved.js
@@ -35,7 +35,7 @@ assert_test_interleaved_statements(test_interleaved_statements());
%OptimizeMaglevOnNextCall(test_interleaved_statements);
assert_test_interleaved_statements(test_interleaved_statements());
assertOptimized(test_interleaved_statements);
-assertTrue(isMaglevved(test_interleaved_statements));
+assertMaglevved(test_interleaved_statements);
assert_test_interleaved_statements(test_interleaved_statements());
%OptimizeFunctionOnNextCall(test_interleaved_statements);
assert_test_interleaved_statements(test_interleaved_statements());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-lazy-override-builtin.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-lazy-override-builtin.js
index b79c99be0ed..783ac6a1c24 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-lazy-override-builtin.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-lazy-override-builtin.js
@@ -31,7 +31,7 @@ assert_test_lazy_override_builtin(test_lazy_override_builtin(Set));
%OptimizeMaglevOnNextCall(test_lazy_override_builtin);
assert_test_lazy_override_builtin(test_lazy_override_builtin(Set));
assertOptimized(test_lazy_override_builtin);
-assertTrue(isMaglevved(test_lazy_override_builtin));
+assertMaglevved(test_lazy_override_builtin);
assert_test_lazy_override_builtin(test_lazy_override_builtin(Set));
%OptimizeFunctionOnNextCall(test_lazy_override_builtin);
assert_test_lazy_override_builtin(test_lazy_override_builtin(Set));
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-limit.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-limit.js
index 2c169645399..a9fa5c63635 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-limit.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-limit.js
@@ -35,7 +35,7 @@ assert_test_count_limit(test_count_limit());
%OptimizeMaglevOnNextCall(test_count_limit);
assert_test_count_limit(test_count_limit());
assertOptimized(test_count_limit);
-assertTrue(isMaglevved(test_count_limit));
+assertMaglevved(test_count_limit);
assert_test_count_limit(test_count_limit());
%OptimizeFunctionOnNextCall(test_count_limit);
assert_test_count_limit(test_count_limit());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto-strict.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto-strict.js
index afcd5fbe676..6b8a7806c59 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto-strict.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto-strict.js
@@ -50,7 +50,7 @@ assert_test_locked_proto(test_locked_proto());
%OptimizeMaglevOnNextCall(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
assertOptimized(test_locked_proto);
-assertTrue(isMaglevved(test_locked_proto));
+assertMaglevved(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
%OptimizeFunctionOnNextCall(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto.js
index 02af4a8b756..35b2798ed54 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-locked-proto.js
@@ -47,7 +47,7 @@ assert_test_locked_proto(test_locked_proto());
%OptimizeMaglevOnNextCall(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
assertOptimized(test_locked_proto);
-assertTrue(isMaglevved(test_locked_proto));
+assertMaglevved(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
%OptimizeFunctionOnNextCall(test_locked_proto);
assert_test_locked_proto(test_locked_proto());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects-strict.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects-strict.js
index ec6b7895223..825bf37ae6c 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects-strict.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects-strict.js
@@ -41,7 +41,7 @@ assert_test_non_extensible_objects(test_non_extensible_objects());
%OptimizeMaglevOnNextCall(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
assertOptimized(test_non_extensible_objects);
-assertTrue(isMaglevved(test_non_extensible_objects));
+assertMaglevved(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
%OptimizeFunctionOnNextCall(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects.js
index bad7611ad22..b852d982e56 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-extensible-objects.js
@@ -38,7 +38,7 @@ assert_test_non_extensible_objects(test_non_extensible_objects());
%OptimizeMaglevOnNextCall(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
assertOptimized(test_non_extensible_objects);
-assertTrue(isMaglevved(test_non_extensible_objects));
+assertMaglevved(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
%OptimizeFunctionOnNextCall(test_non_extensible_objects);
assert_test_non_extensible_objects(test_non_extensible_objects());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-literal.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-literal.js
index f8994591dc2..43d6def6a7b 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-literal.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-non-literal.js
@@ -32,7 +32,7 @@ assert_test_non_literal_value(test_non_literal_value());
%OptimizeMaglevOnNextCall(test_non_literal_value);
assert_test_non_literal_value(test_non_literal_value());
assertOptimized(test_non_literal_value);
-assertTrue(isMaglevved(test_non_literal_value));
+assertMaglevved(test_non_literal_value);
assert_test_non_literal_value(test_non_literal_value());
%OptimizeFunctionOnNextCall(test_non_literal_value);
assert_test_non_literal_value(test_non_literal_value());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-function.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-function.js
index 29a87cea9f9..42fed4c7724 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-function.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-function.js
@@ -38,7 +38,7 @@ assert_test_not_function(test_not_function());
%OptimizeMaglevOnNextCall(test_not_function);
assert_test_not_function(test_not_function());
assertOptimized(test_not_function);
-assertTrue(isMaglevved(test_not_function));
+assertMaglevved(test_not_function);
assert_test_not_function(test_not_function());
%OptimizeFunctionOnNextCall(test_not_function);
assert_test_not_function(test_not_function());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-proto-assign-seq.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-proto-assign-seq.js
index 8ff446d3dfd..cbe768fffa2 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-proto-assign-seq.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-not-proto-assign-seq.js
@@ -48,7 +48,7 @@ assert_test_not_proto_assign_seq(test_not_proto_assign_seq());
%OptimizeMaglevOnNextCall(test_not_proto_assign_seq);
assert_test_not_proto_assign_seq(test_not_proto_assign_seq());
assertOptimized(test_not_proto_assign_seq);
-assertTrue(isMaglevved(test_not_proto_assign_seq));
+assertMaglevved(test_not_proto_assign_seq);
assert_test_not_proto_assign_seq(test_not_proto_assign_seq());
%OptimizeFunctionOnNextCall(test_not_proto_assign_seq);
assert_test_not_proto_assign_seq(test_not_proto_assign_seq());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-null-prototype.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-null-prototype.js
index 15d7fbbfee0..b140627b36e 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-null-prototype.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-null-prototype.js
@@ -44,7 +44,7 @@ test_null_prototype();
%OptimizeMaglevOnNextCall(test_null_prototype);
test_null_prototype();
assertOptimized(test_null_prototype);
-assertTrue(isMaglevved(test_null_prototype));
+assertMaglevved(test_null_prototype);
test_null_prototype();
%OptimizeFunctionOnNextCall(test_null_prototype);
test_null_prototype();
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-assign.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-assign.js
index 6863939e3a1..e3645522d53 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-assign.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-assign.js
@@ -37,7 +37,7 @@ assert_test_object_assign(test_object_assign());
%OptimizeMaglevOnNextCall(test_object_assign);
assert_test_object_assign(test_object_assign());
assertOptimized(test_object_assign);
-assertTrue(isMaglevved(test_object_assign));
+assertMaglevved(test_object_assign);
assert_test_object_assign(test_object_assign());
%OptimizeFunctionOnNextCall(test_object_assign);
assert_test_object_assign(test_object_assign());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-entries.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-entries.js
index 733851043b5..594da53bc0c 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-entries.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-entries.js
@@ -37,7 +37,7 @@ assert_test_object_entries(test_object_entries());
%OptimizeMaglevOnNextCall(test_object_entries);
assert_test_object_entries(test_object_entries());
assertOptimized(test_object_entries);
-assertTrue(isMaglevved(test_object_entries));
+assertMaglevved(test_object_entries);
assert_test_object_entries(test_object_entries());
}
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-values.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-values.js
index b7d07a4572f..342bf7dc58f 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-values.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-object-values.js
@@ -31,7 +31,7 @@ assert_test_object_values(test_object_values());
%OptimizeMaglevOnNextCall(test_object_values);
assert_test_object_values(test_object_values());
assertOptimized(test_object_values);
-assertTrue(isMaglevved(test_object_values));
+assertMaglevved(test_object_values);
assert_test_object_values(test_object_values());
%OptimizeFunctionOnNextCall(test_object_values);
assert_test_object_values(test_object_values());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-poison-default-proto.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-poison-default-proto.js
index 23749d244d3..aeb2aeab6e0 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-poison-default-proto.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-poison-default-proto.js
@@ -49,7 +49,7 @@ assert_test_poison_default_proto(test_poison_default_proto());
%OptimizeMaglevOnNextCall(test_poison_default_proto);
assert_test_poison_default_proto(test_poison_default_proto());
assertOptimized(test_poison_default_proto);
-assertTrue(isMaglevved(test_poison_default_proto));
+assertMaglevved(test_poison_default_proto);
assert_test_poison_default_proto(test_poison_default_proto());
%OptimizeFunctionOnNextCall(test_poison_default_proto);
assert_test_poison_default_proto(test_poison_default_proto());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-preserve-descriptor.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-preserve-descriptor.js
index 8b15f166bec..3d4e954c41e 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-preserve-descriptor.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-preserve-descriptor.js
@@ -45,7 +45,7 @@ assert_test_preserve_descriptor(test_preserve_descriptor());
%OptimizeMaglevOnNextCall(test_preserve_descriptor);
assert_test_preserve_descriptor(test_preserve_descriptor());
assertOptimized(test_preserve_descriptor);
-assertTrue(isMaglevved(test_preserve_descriptor));
+assertMaglevved(test_preserve_descriptor);
assert_test_preserve_descriptor(test_preserve_descriptor());
%OptimizeFunctionOnNextCall(test_preserve_descriptor);
assert_test_preserve_descriptor(test_preserve_descriptor());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-of-prototype-assigned.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-of-prototype-assigned.js
index 104ba55222b..b9d52ed3f5d 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-of-prototype-assigned.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-of-prototype-assigned.js
@@ -41,7 +41,7 @@ assert_test_proto_of_prototype_assigned(test_proto_of_prototype_assigned());
%OptimizeMaglevOnNextCall(test_proto_of_prototype_assigned);
assert_test_proto_of_prototype_assigned(test_proto_of_prototype_assigned());
assertOptimized(test_proto_of_prototype_assigned);
-assertTrue(isMaglevved(test_proto_of_prototype_assigned));
+assertMaglevved(test_proto_of_prototype_assigned);
assert_test_proto_of_prototype_assigned(test_proto_of_prototype_assigned());
%OptimizeFunctionOnNextCall(test_proto_of_prototype_assigned);
assert_test_proto_of_prototype_assigned(test_proto_of_prototype_assigned());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-prop.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-prop.js
index ce61ae441a0..8178b3e1ed0 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-prop.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-proto-prop.js
@@ -34,7 +34,7 @@ assert_test_proto_assignment(test_proto_assignment());
%OptimizeMaglevOnNextCall(test_proto_assignment);
assert_test_proto_assignment(test_proto_assignment());
assertOptimized(test_proto_assignment);
-assertTrue(isMaglevved(test_proto_assignment));
+assertMaglevved(test_proto_assignment);
assert_test_proto_assignment(test_proto_assignment());
%OptimizeFunctionOnNextCall(test_proto_assignment);
assert_test_proto_assignment(test_proto_assignment());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-proto-keys.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-proto-keys.js
index 6ec836bf4c9..09931de9464 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-proto-keys.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-proto-keys.js
@@ -59,7 +59,7 @@ assert_test_prototype_proto_keys(test_prototype_proto_keys());
%OptimizeMaglevOnNextCall(test_prototype_proto_keys);
assert_test_prototype_proto_keys(test_prototype_proto_keys());
assertOptimized(test_prototype_proto_keys);
-assertTrue(isMaglevved(test_prototype_proto_keys));
+assertMaglevved(test_prototype_proto_keys);
assert_test_prototype_proto_keys(test_prototype_proto_keys());
%OptimizeFunctionOnNextCall(test_prototype_proto_keys);
assert_test_prototype_proto_keys(test_prototype_proto_keys());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-read-only.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-read-only.js
index cec73c40fd7..eae274ae81b 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-read-only.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-prototype-read-only.js
@@ -56,7 +56,7 @@ assert_test_prototype_read_only(test_prototype_read_only());
%OptimizeMaglevOnNextCall(test_prototype_read_only);
assert_test_prototype_read_only(test_prototype_read_only());
assertOptimized(test_prototype_read_only);
-assertTrue(isMaglevved(test_prototype_read_only));
+assertMaglevved(test_prototype_read_only);
assert_test_prototype_read_only(test_prototype_read_only());
%OptimizeFunctionOnNextCall(test_prototype_read_only);
assert_test_prototype_read_only(test_prototype_read_only());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-readonly-chain.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-readonly-chain.js
index 9c374f96493..850618838a4 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-readonly-chain.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-readonly-chain.js
@@ -54,7 +54,7 @@ assert_test_readonly_chain(test_readonly_chain());
%OptimizeMaglevOnNextCall(test_readonly_chain);
assert_test_readonly_chain(test_readonly_chain());
assertOptimized(test_readonly_chain);
-assertTrue(isMaglevved(test_readonly_chain));
+assertMaglevved(test_readonly_chain);
assert_test_readonly_chain(test_readonly_chain());
%OptimizeFunctionOnNextCall(test_readonly_chain);
assert_test_readonly_chain(test_readonly_chain());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reassign-local.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reassign-local.js
index a1bbb1c2894..8151ba73f13 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reassign-local.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reassign-local.js
@@ -42,7 +42,7 @@ assert_test_reassign_local(test_reassign_local());
%OptimizeMaglevOnNextCall(test_reassign_local);
assert_test_reassign_local(test_reassign_local());
assertOptimized(test_reassign_local);
-assertTrue(isMaglevved(test_reassign_local));
+assertMaglevved(test_reassign_local);
assert_test_reassign_local(test_reassign_local());
%OptimizeFunctionOnNextCall(test_reassign_local);
assert_test_reassign_local(test_reassign_local());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get-own-property-descriptor.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get-own-property-descriptor.js
index 0bde32a0e2b..b25c6e81e7e 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get-own-property-descriptor.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get-own-property-descriptor.js
@@ -32,7 +32,7 @@ assert_test_reflect_getOwnPropertyDescriptor(test_reflect_getOwnPropertyDescript
%OptimizeMaglevOnNextCall(test_reflect_getOwnPropertyDescriptor);
assert_test_reflect_getOwnPropertyDescriptor(test_reflect_getOwnPropertyDescriptor());
assertOptimized(test_reflect_getOwnPropertyDescriptor);
-assertTrue(isMaglevved(test_reflect_getOwnPropertyDescriptor));
+assertMaglevved(test_reflect_getOwnPropertyDescriptor);
assert_test_reflect_getOwnPropertyDescriptor(test_reflect_getOwnPropertyDescriptor());
%OptimizeFunctionOnNextCall(test_reflect_getOwnPropertyDescriptor);
assert_test_reflect_getOwnPropertyDescriptor(test_reflect_getOwnPropertyDescriptor());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get.js
index 64b9b3e4225..a6273fa14c7 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-reflect-get.js
@@ -31,7 +31,7 @@ assert_test_reflect_get(test_reflect_get());
%OptimizeMaglevOnNextCall(test_reflect_get);
assert_test_reflect_get(test_reflect_get());
assertOptimized(test_reflect_get);
-assertTrue(isMaglevved(test_reflect_get));
+assertMaglevved(test_reflect_get);
assert_test_reflect_get(test_reflect_get());
%OptimizeFunctionOnNextCall(test_reflect_get);
assert_test_reflect_get(test_reflect_get());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-setter-chain.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-setter-chain.js
index ee17cd38686..e12ccc8767f 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-setter-chain.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-setter-chain.js
@@ -63,7 +63,7 @@ assert_test_setter_chain(test_setter_chain());
%OptimizeMaglevOnNextCall(test_setter_chain);
assert_test_setter_chain(test_setter_chain());
assertOptimized(test_setter_chain);
-assertTrue(isMaglevved(test_setter_chain));
+assertMaglevved(test_setter_chain);
assert_test_setter_chain(test_setter_chain());
%OptimizeFunctionOnNextCall(test_setter_chain);
assert_test_setter_chain(test_setter_chain());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-shadow.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-shadow.js
index 72f30c4de50..707289a7ce1 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-shadow.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-shadow.js
@@ -40,7 +40,7 @@ assert_test_shadow_properties(test_shadow_properties());
%OptimizeMaglevOnNextCall(test_shadow_properties);
assert_test_shadow_properties(test_shadow_properties());
assertOptimized(test_shadow_properties);
-assertTrue(isMaglevved(test_shadow_properties));
+assertMaglevved(test_shadow_properties);
assert_test_shadow_properties(test_shadow_properties());
%OptimizeFunctionOnNextCall(test_shadow_properties);
assert_test_shadow_properties(test_shadow_properties());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-modified.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-modified.js
index 261ffe9eea5..35ab03164e7 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-modified.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-modified.js
@@ -40,7 +40,7 @@ assert_test_slow_path_modified_proto(test_slow_path_modified_proto());
%OptimizeMaglevOnNextCall(test_slow_path_modified_proto);
assert_test_slow_path_modified_proto(test_slow_path_modified_proto());
assertOptimized(test_slow_path_modified_proto);
-assertTrue(isMaglevved(test_slow_path_modified_proto));
+assertMaglevved(test_slow_path_modified_proto);
assert_test_slow_path_modified_proto(test_slow_path_modified_proto());
%OptimizeFunctionOnNextCall(test_slow_path_modified_proto);
assert_test_slow_path_modified_proto(test_slow_path_modified_proto());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-non-extensible.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-non-extensible.js
index 27057407dac..b842488f2cf 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-non-extensible.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-slow-non-extensible.js
@@ -32,7 +32,7 @@ assert_test_slow_path_non_extensible(test_slow_path_non_extensible());
%OptimizeMaglevOnNextCall(test_slow_path_non_extensible);
assert_test_slow_path_non_extensible(test_slow_path_non_extensible());
assertOptimized(test_slow_path_non_extensible);
-assertTrue(isMaglevved(test_slow_path_non_extensible));
+assertMaglevved(test_slow_path_non_extensible);
assert_test_slow_path_non_extensible(test_slow_path_non_extensible());
%OptimizeFunctionOnNextCall(test_slow_path_non_extensible);
assert_test_slow_path_non_extensible(test_slow_path_non_extensible());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-spreading.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-spreading.js
index 4218cc8f714..d528cb2e27d 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-spreading.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-spreading.js
@@ -38,7 +38,7 @@ assert_test_spreading(test_spreading());
%OptimizeMaglevOnNextCall(test_spreading);
assert_test_spreading(test_spreading());
assertOptimized(test_spreading);
-assertTrue(isMaglevved(test_spreading));
+assertMaglevved(test_spreading);
assert_test_spreading(test_spreading());
}
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-strict.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-strict.js
index c1cd285174b..2490124f0ac 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-strict.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-strict.js
@@ -32,7 +32,7 @@ assert_test_strict_mode(test_strict_mode());
%OptimizeMaglevOnNextCall(test_strict_mode);
assert_test_strict_mode(test_strict_mode());
assertOptimized(test_strict_mode);
-assertTrue(isMaglevved(test_strict_mode));
+assertMaglevved(test_strict_mode);
assert_test_strict_mode(test_strict_mode());
%OptimizeFunctionOnNextCall(test_strict_mode);
assert_test_strict_mode(test_strict_mode());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-structured-clone.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-structured-clone.js
index d3bd8850703..e69b8deaf06 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-structured-clone.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-structured-clone.js
@@ -35,7 +35,7 @@ assert_test_structured_clone(test_structured_clone());
%OptimizeMaglevOnNextCall(test_structured_clone);
assert_test_structured_clone(test_structured_clone());
assertOptimized(test_structured_clone);
-assertTrue(isMaglevved(test_structured_clone));
+assertMaglevved(test_structured_clone);
assert_test_structured_clone(test_structured_clone());
%OptimizeFunctionOnNextCall(test_structured_clone);
assert_test_structured_clone(test_structured_clone());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy-eval.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy-eval.js
index 96363df82f2..c9131b7e55b 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy-eval.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy-eval.js
@@ -40,7 +40,7 @@ assert_test_variable_proxy_eval(test_variable_proxy_eval());
%OptimizeMaglevOnNextCall(test_variable_proxy_eval);
assert_test_variable_proxy_eval(test_variable_proxy_eval());
assertOptimized(test_variable_proxy_eval);
-assertTrue(isMaglevved(test_variable_proxy_eval));
+assertMaglevved(test_variable_proxy_eval);
assert_test_variable_proxy_eval(test_variable_proxy_eval());
%OptimizeFunctionOnNextCall(test_variable_proxy_eval);
assert_test_variable_proxy_eval(test_variable_proxy_eval());
diff --git a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy.js b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy.js
index 04fa4fcfc2f..c0a85579cea 100644
--- a/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy.js
+++ b/deps/v8/test/mjsunit/opt-proto-seq/proto-seq-opt-variable-proxy.js
@@ -48,7 +48,7 @@ assert_test_variable_proxy(test_variable_proxy());
%OptimizeMaglevOnNextCall(test_variable_proxy);
assert_test_variable_proxy(test_variable_proxy());
assertOptimized(test_variable_proxy);
-assertTrue(isMaglevved(test_variable_proxy));
+assertMaglevved(test_variable_proxy);
assert_test_variable_proxy(test_variable_proxy());
%OptimizeFunctionOnNextCall(test_variable_proxy);
assert_test_variable_proxy(test_variable_proxy());
diff --git a/deps/v8/test/mjsunit/private_fields/test_private_fields.js b/deps/v8/test/mjsunit/private_fields/test_private_fields.js
index 941365157e9..e405cf64b25 100644
--- a/deps/v8/test/mjsunit/private_fields/test_private_fields.js
+++ b/deps/v8/test/mjsunit/private_fields/test_private_fields.js
@@ -113,12 +113,12 @@ assert_test_private_fields(test_private_fields());
assert_test_private_fields(test_private_fields());
-// assertTrue(isMaglevved(TestClass.prototype.setPrivate));
-// assertTrue(isMaglevved(TestClass.prototype.getPrivate));
-// assertTrue(isMaglevved(TestClass.prototype.incPrivate));
-// assertTrue(isMaglevved(TestClass.prototype.add2Private));
-// assertTrue(isMaglevved(TestClass.prototype.force_context_depth));
-// assertTrue(isMaglevved(test_private_fields));
+// assertMaglevved(TestClass.prototype.setPrivate);
+// assertMaglevved(TestClass.prototype.getPrivate);
+// assertMaglevved(TestClass.prototype.incPrivate);
+// assertMaglevved(TestClass.prototype.add2Private);
+// assertMaglevved(TestClass.prototype.force_context_depth);
+// assertMaglevved(test_private_fields);
assert_test_private_fields(test_private_fields());
diff --git a/deps/v8/test/mjsunit/regress/regress-1320641.js b/deps/v8/test/mjsunit/regress/regress-1320641.js
index 6bd109421a9..0ca6a414123 100644
--- a/deps/v8/test/mjsunit/regress/regress-1320641.js
+++ b/deps/v8/test/mjsunit/regress/regress-1320641.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --mock-arraybuffer-allocator
function foo(){
const xs = new Uint16Array(3775336418);
diff --git a/deps/v8/test/mjsunit/regress/regress-395028748.js b/deps/v8/test/mjsunit/regress/regress-395028748.js
index c70368bb7c0..ccd9fe5ab58 100644
--- a/deps/v8/test/mjsunit/regress/regress-395028748.js
+++ b/deps/v8/test/mjsunit/regress/regress-395028748.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --expose-fast-api
+// Flags: --allow-natives-syntax --expose-fast-api --turbofan
const fast_api = new d8.test.FastCAPI();
diff --git a/deps/v8/test/mjsunit/regress/regress-424627229.js b/deps/v8/test/mjsunit/regress/regress-424627229.js
index 4321a22c02f..6a66eb2ed94 100644
--- a/deps/v8/test/mjsunit/regress/regress-424627229.js
+++ b/deps/v8/test/mjsunit/regress/regress-424627229.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --expose-fast-api --no-lazy-feedback-allocation
+// Flags: --allow-natives-syntax --expose-fast-api --no-lazy-feedback-allocation --turbofan
const Probe =function() {
function probe() {
let handler = {
diff --git a/deps/v8/test/mjsunit/regress/regress-438321229.js b/deps/v8/test/mjsunit/regress/regress-438321229.js
index ca457e1dde4..bb41bc1db0e 100644
--- a/deps/v8/test/mjsunit/regress/regress-438321229.js
+++ b/deps/v8/test/mjsunit/regress/regress-438321229.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --expose-fast-api --no-lazy-feedback-allocation
+// Flags: --allow-natives-syntax --expose-fast-api --no-lazy-feedback-allocation --turbofan
const t0 = d8.test.FastCAPI;
const v5 = new t0();
diff --git a/deps/v8/test/mjsunit/regress/regress-499527555-2.js b/deps/v8/test/mjsunit/regress/regress-499527555-2.js
index fa6a7fb7c02..cc151ed79a3 100644
--- a/deps/v8/test/mjsunit/regress/regress-499527555-2.js
+++ b/deps/v8/test/mjsunit/regress/regress-499527555-2.js
@@ -1,6 +1,7 @@
// Copyright 2026 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.
+// Flags: --multi-mapped-mock-allocator
const sz = 0x100000000 + 64 * 1024; // 4GB + 64Kb
let buf;
diff --git a/deps/v8/test/mjsunit/regress/regress-499527555.js b/deps/v8/test/mjsunit/regress/regress-499527555.js
index 84d753b5551..17e097568fb 100644
--- a/deps/v8/test/mjsunit/regress/regress-499527555.js
+++ b/deps/v8/test/mjsunit/regress/regress-499527555.js
@@ -1,6 +1,7 @@
// Copyright 2026 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.
+// Flags: --multi-mapped-mock-allocator
const sz = 0x100000000 + 64 * 1024; // 4GB + 64Kb
let sab;
diff --git a/deps/v8/test/mjsunit/regress/regress-506178478.js b/deps/v8/test/mjsunit/regress/regress-506178478.js
new file mode 100644
index 00000000000..d02ddcc66a4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-506178478.js
@@ -0,0 +1,22 @@
+// Copyright 2026 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.
+
+// Flags: --no-concurrent-recompilation
+// Flags: --invocation-count-for-turbofan=1000000000
+// Flags: --invocation-count-for-feedback-allocation=1
+// Flags: --invocation-count-for-maglev=1
+
+function f(x) {
+ return x + 1;
+}
+for (let i = 0; i < 20; i++) {
+ assertEquals(i + 1, f(i));
+}
+
+function g(o) {
+ return o.p;
+}
+for (let i = 0; i < 10; i++) {
+ assertEquals(i, g({p: i, ["a" + i]: i}));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-509312809.js b/deps/v8/test/mjsunit/regress/regress-509312809.js
index 1651794b44a..a646065fbc5 100644
--- a/deps/v8/test/mjsunit/regress/regress-509312809.js
+++ b/deps/v8/test/mjsunit/regress/regress-509312809.js
@@ -1,6 +1,7 @@
// Copyright 2026 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.
+// Flags: --multi-mapped-mock-allocator
const v2 = new Uint8Array(4294967296);
for (let v3 = 0; v3 < 25; v3++) {
diff --git a/deps/v8/test/mjsunit/regress/regress-511279942.js b/deps/v8/test/mjsunit/regress/regress-511279942.js
index 03430e99b24..b5ac6d3b9dc 100644
--- a/deps/v8/test/mjsunit/regress/regress-511279942.js
+++ b/deps/v8/test/mjsunit/regress/regress-511279942.js
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --stress-compaction --allow-natives-syntax --dispatch-table-gc-interval=1
+// Flags: --stress-compaction --allow-natives-syntax
+
+%SetDispatchTableGCInterval(1);
function outer() {
return [
diff --git a/deps/v8/test/mjsunit/regress/regress-519652102.js b/deps/v8/test/mjsunit/regress/regress-519652102.js
new file mode 100644
index 00000000000..e5f6e66f56b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-519652102.js
@@ -0,0 +1,17 @@
+// Copyright 2026 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.
+
+// Flags: --stress-lazy-source-positions
+
+(function f() {
+ {
+ let force_block_scope;
+ eval(`
+ {
+ function f() {}
+ }
+ var g = (function g() { f(); })
+ `);
+ }
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-525472602.js b/deps/v8/test/mjsunit/regress/regress-525472602.js
new file mode 100644
index 00000000000..29d1d43a621
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-525472602.js
@@ -0,0 +1,16 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+let o = new Array(1073741825);
+o[0] = 1; // Force dictionary elements initially
+let sep = {
+ toString() {
+ o.length = 0;
+ o.push(1); // HOLEY_SMI_ELEMENTS
+ return ",";
+ }
+};
+assertThrows(() => o.join(sep), RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-558568713.js b/deps/v8/test/mjsunit/regress/regress-558568713.js
new file mode 100644
index 00000000000..43a5da2e025
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-558568713.js
@@ -0,0 +1,21 @@
+// Copyright 2026 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.
+
+try {
+ let padding = " ".repeat(270000000);
+ let params = [];
+ for (let i = 0; i < 16384; i++) {
+ params.push("p" + i);
+ }
+ params.push("p16384=1");
+ let param_str = params.join(",");
+ let inner_funcs = "";
+ for (let i = 0; i < 16400; i++) {
+ inner_funcs += "function f" + i + "(){}\n";
+ }
+ let code = "function outer() {\n function inner(" + param_str + ") {\n" + inner_funcs + " }\n}\n";
+ eval(padding + code);
+} catch (e) {
+ assertInstanceof(e, RangeError);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-559266116.js b/deps/v8/test/mjsunit/regress/regress-559266116.js
new file mode 100644
index 00000000000..14bc7bcc5b6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-559266116.js
@@ -0,0 +1,20 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+const key1 = String.fromCharCode(49, 48, 48, 48, 0x130, 48, 48, 48, 48, 48)
+ .replace(/(\u0130)()/g, '$2');
+Symbol.for(key1);
+const object1 =
+ (0, eval)(`({${key1}(v){return Object.values({"${key1}":v})[1]}})`);
+assertEquals(undefined, object1[key1](1));
+
+const key2 = String.fromCharCode(49, 48, 48, 48, 0x130, 48, 48, 48, 48, 49)
+ .replace(/(\u0130)()/g, '$2');
+new Set().add(key2);
+Symbol.for(key2);
+const object2 =
+ (0, eval)(`({${key2}(v){return Object.values({"${key2}":v})[1]}})`);
+assertEquals(undefined, object2[key2](1));
diff --git a/deps/v8/test/mjsunit/regress/regress-559408989.js b/deps/v8/test/mjsunit/regress/regress-559408989.js
new file mode 100644
index 00000000000..fc127fbe9b2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-559408989.js
@@ -0,0 +1,24 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Foo() {}
+// Deleting Foo.name causes constructor debug name lookup to fall back to
+// searching the prototype chain via GetDataProperty().
+delete Foo.name;
+// Bound functions implement "name" via a lazy AccessorInfo getter
+// (BoundFunctionNameGetter) with SideEffectType::kHasNoSideEffect that
+// allocates a string on the heap ("bound bar").
+Object.setPrototypeOf(Foo, (function bar() {}).bind());
+
+const obj = new Foo();
+obj.self = obj;
+
+// JSON.stringify should fail with a TypeError due to the circular structure.
+// Under DisallowGarbageCollection, GetDataProperty() must not execute
+// accessors that allocate memory.
+const expectedMessage =
+ "Converting circular structure to JSON\n" +
+ " --> starting at object with constructor 'Foo'\n" +
+ " --- property 'self' closes the circle";
+assertThrows(() => JSON.stringify(obj), TypeError, expectedMessage);
diff --git a/deps/v8/test/mjsunit/regress/regress-559536931.js b/deps/v8/test/mjsunit/regress/regress-559536931.js
new file mode 100644
index 00000000000..0f1729b2787
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-559536931.js
@@ -0,0 +1,38 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --expose-gc
+// Flags: --turbolev --no-lazy-feedback-allocation
+
+function wrap(f, permissive = true) {
+ try {
+ return f();
+ } catch (e) {
+ }
+}
+%PrepareFunctionForOptimization(wrap);
+
+function f1(useSmi, returnEarly) {
+ if (returnEarly) return;
+ let obj = { a: 1 };
+ let arrow = () => useSmi ? 42 : obj;
+ // Important that we don't do %PrepareFunctionForOptimization(arrow) here
+ let objOrSmi = wrap(arrow);
+ objOrSmi | -6;
+ obj.a = objOrSmi; // This is the offending store
+ return obj;
+}
+f1(true);
+
+%PretenureAllocationSite(f1(true));
+
+gc({});
+
+function f2(returnEarly) {
+ return f1(false, returnEarly);
+}
+%PrepareFunctionForOptimization(f2);
+f2(true);
+%OptimizeFunctionOnNextCall(f2);
+f2(true);
diff --git a/deps/v8/test/mjsunit/regress/regress-560730175.js b/deps/v8/test/mjsunit/regress/regress-560730175.js
new file mode 100644
index 00000000000..82dcd140e5f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-560730175.js
@@ -0,0 +1,31 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+// NormalizedMapCache was indexed by a hash of the prototype and bit_field2
+// only. A JSFunction and a plain object with prototype Function.prototype
+// hashed to the same entry although they are never
+// EquivalentToForNormalization, so alternating normalizations at the two
+// sites evicted each other and no two objects shared a dictionary map.
+// Including the instance type in the mixed hash lets these two sites use
+// different entries and reuse their normalized maps.
+
+const fns = [];
+const objs = [];
+for (let i = 0; i < 20; i++) {
+ const f = function() {};
+ delete f.length;
+ fns.push(f);
+ const o = Object.create(Function.prototype);
+ o.a = 1;
+ delete o.a;
+ objs.push(o);
+}
+assertFalse(%HasFastProperties(fns[0]));
+assertFalse(%HasFastProperties(objs[0]));
+for (let i = 1; i < fns.length; i++) {
+ assertTrue(%HaveSameMap(fns[0], fns[i]));
+ assertTrue(%HaveSameMap(objs[0], objs[i]));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-561116893.js b/deps/v8/test/mjsunit/regress/regress-561116893.js
new file mode 100644
index 00000000000..9be1df1529b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-561116893.js
@@ -0,0 +1,10 @@
+// Copyright 2026 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.
+
+// Flags: --stress-background-compile --stress-flush-code --expose-gc
+
+let code = "globalThis.keepAlive = () => { 'use strict'; return eval('1'); }; globalThis.keepAlive();";
+Realm.eval(Realm.current(), code);
+for (let i = 0; i < 10; i++) gc({type: 'major'});
+Realm.eval(Realm.current(), code);
diff --git a/deps/v8/test/mjsunit/regress/regress-562529689.js b/deps/v8/test/mjsunit/regress/regress-562529689.js
new file mode 100644
index 00000000000..f6b6cbdd1dc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-562529689.js
@@ -0,0 +1,10 @@
+// Copyright 2026 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.
+
+// Flags: --js-nonextensible-applies-to-private
+
+d8.debugger.enable();
+let p = new Promise(() => {});
+Object.preventExtensions(p);
+assertDoesNotThrow(() => new Promise(resolve => resolve(p)));
diff --git a/deps/v8/test/mjsunit/regress/regress-562557292.js b/deps/v8/test/mjsunit/regress/regress-562557292.js
new file mode 100644
index 00000000000..4ee6baf248c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-562557292.js
@@ -0,0 +1,41 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev
+
+// The graph builder stops unwrapping bound functions at kMaxBoundFunctionDepth
+// and emits an OrdinaryHasInstance builtin call with the remaining callable as
+// a constant. The graph optimizer must not resume unwrapping that chain: it
+// would emit map checks, and the CallBuiltin it is visiting has no eager deopt
+// info to hang them off.
+
+function RealCtor() {}
+
+// One level deeper than kMaxBoundFunctionDepth. Built before RealCtor loses
+// Function.prototype, which is where bind lives.
+let bound_chain = RealCtor;
+for (let i = 0; i < 6; ++i) bound_chain = bound_chain.bind(null);
+
+// Without Function.prototype in the chain, @@hasInstance is not found, which is
+// the reduction path that emits map checks.
+Object.setPrototypeOf(RealCtor, null);
+RealCtor.x = 1;
+
+// Transition a sibling off RealCtor's map to make that map unstable, so the
+// reduction emits a CheckMaps instead of taking a stable map dependency.
+function DummyCtor() {}
+Object.setPrototypeOf(DummyCtor, null);
+DummyCtor.x = 1;
+DummyCtor.y = 2;
+
+function test(o) {
+ return o instanceof bound_chain;
+}
+
+%PrepareFunctionForOptimization(test);
+assertFalse(test({}));
+assertTrue(test(new RealCtor()));
+%OptimizeFunctionOnNextCall(test);
+assertFalse(test({}));
+assertTrue(test(new RealCtor()));
diff --git a/deps/v8/test/mjsunit/regress/regress-563764306.js b/deps/v8/test/mjsunit/regress/regress-563764306.js
new file mode 100644
index 00000000000..251e9fe4afd
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-563764306.js
@@ -0,0 +1,22 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --expose-gc --log-deopt --logfile='+'
+
+// Optimized code weakly references the maps it was specialized for. When such
+// a map dies, the GC marks the dependent code for deoptimization from a
+// background thread which has no LocalHeap, so logging that event must not
+// create handles.
+
+function load(obj) {
+ return obj.c;
+}
+
+for (let i = 0; i < 200; i++) {
+ %PrepareFunctionForOptimization(load);
+ load({a: i, b: i});
+ load({c: i});
+ %OptimizeFunctionOnNextCall(load);
+ if (i % 5 === 0) gc();
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-564625827.js b/deps/v8/test/mjsunit/regress/regress-564625827.js
new file mode 100644
index 00000000000..b9cbdfabb29
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-564625827.js
@@ -0,0 +1,28 @@
+// Copyright 2026 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.
+
+// Flags: --stress-incremental-marking
+
+this.performance.measureMemory();
+const kRingSize = 2048;
+const ring = new Array(kRingSize);
+const sabRing = new Array(kRingSize);
+let index = 0;
+for (let i = 0; i < 100000; i++) {
+ const ta = new Uint8Array();
+ const prev = ring[index];
+ if (prev !== undefined) {
+ prev.buffer;
+ }
+ ring[index] = ta;
+
+ const gsab = new SharedArrayBuffer(16, {maxByteLength: 64});
+ const prevSab = sabRing[index];
+ if (prevSab !== undefined) {
+ prevSab.grow(32);
+ }
+ sabRing[index] = gsab;
+
+ index = (index + 1) % kRingSize;
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-565836459.js b/deps/v8/test/mjsunit/regress/regress-565836459.js
new file mode 100644
index 00000000000..d826f528113
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-565836459.js
@@ -0,0 +1,32 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Target() {}
+const proxy_proto = new Proxy({}, {});
+Target.prototype = proxy_proto;
+
+function NewTarget() {}
+NewTarget.prototype = proxy_proto;
+
+class Base {
+ constructor(o) {
+ return o;
+ }
+}
+
+class DefineY extends Base {
+ y = 1.1;
+}
+
+for (let i = 0; i < 10; i++) {
+ new DefineY({});
+}
+
+// Create a Smi transition for .y on the derived map.
+Reflect.construct(Target, [], NewTarget).y = 1;
+
+// Trigger a Smi -> Double field generalization via DefineNamedOwnIC on the
+// derived map.
+const victim = new DefineY(Reflect.construct(Target, [], NewTarget));
+assertEquals(1.1, victim.y);
diff --git a/deps/v8/test/mjsunit/regress/regress-566243375.js b/deps/v8/test/mjsunit/regress/regress-566243375.js
new file mode 100644
index 00000000000..6cf03c5f29b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-566243375.js
@@ -0,0 +1,12 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class C extends Object {
+ constructor() {
+ console.trace();
+ super();
+ }
+}
+
+new C();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-388320179.js b/deps/v8/test/mjsunit/regress/regress-crbug-388320179.js
new file mode 100644
index 00000000000..311b697a60f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-388320179.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+// The heap broker caches a JSFunction's prototype, which may be another
+// JSFunction. Caching a chain of them must not recurse, or compiling any
+// function that refers to the head of the chain overflows the stack.
+
+// Links alternate between the two ways the broker reaches the next function:
+// directly through the prototype slot, and through the prototype of an initial
+// map. The chain has to outlast the C++ stack; it overflowed at ~22000 links.
+const kChainLength = 80000;
+
+let f = function() {};
+for (let i = 0; i < kChainLength; i++) {
+ const g = function() {};
+ g.prototype = f;
+ if (i % 2) new g(); // Materializes an initial map with prototype {f}.
+ f = g;
+}
+
+const head = f;
+function call_head() { return head(); }
+
+%PrepareFunctionForOptimization(call_head);
+call_head();
+%OptimizeFunctionOnNextCall(call_head);
+assertEquals(undefined, call_head());
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-562108903.js b/deps/v8/test/mjsunit/regress/regress-crbug-562108903.js
new file mode 100644
index 00000000000..bbb4e0317da
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-562108903.js
@@ -0,0 +1,47 @@
+// Copyright 2026 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.
+
+// Canonicalize for /iu and /iv applies simple case folding to each code point
+// separately. Backreference comparison must not use full case folding, under
+// which e.g. U+00DF folds to "ss".
+//
+// Every case is spelled twice: once with literal characters, once with escapes.
+
+// A leading non-Latin1 character forces the two-byte matcher.
+const prefix = 'Ā';
+
+function assertBackrefMismatch(pattern, subject) {
+ assertFalse(new RegExp(pattern, 'iu').test(subject));
+ assertFalse(new RegExp(pattern, 'iv').test(subject));
+}
+
+function assertBackrefMatch(pattern, subject) {
+ assertTrue(new RegExp(pattern, 'iu').test(subject));
+ assertTrue(new RegExp(pattern, 'iv').test(subject));
+}
+
+// U+00DF SHARP S has a full folding to "ss" but no simple folding.
+assertBackrefMismatch(`^${prefix}(..)\\1$`, `${prefix}ßSsß`);
+assertBackrefMismatch(`^${prefix}(..)\\1$`, `${prefix}\u00DFSs\u00DF`);
+
+// U+FB00 LIGATURE FF has a full folding to "ff" but no simple folding.
+assertBackrefMismatch(`^${prefix}(..)\\1$`, `${prefix}ffFfff`);
+assertBackrefMismatch(`^${prefix}(..)\\1$`, `${prefix}\uFB00Ff\uFB00`);
+
+// Simple foldings still match.
+assertBackrefMatch(`^${prefix}(..)\\1$`, `${prefix}AbaB`);
+
+assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}ßß`);
+assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}\u00DF\u00DF`);
+
+// Folding across distinct code points needs the case mapping ICU provides.
+if (typeof Intl !== 'undefined') {
+ // U+1E9E CAPITAL SHARP S folds to U+00DF.
+ assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}ẞß`);
+ assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}\u1E9E\u00DF`);
+
+ // U+212A KELVIN SIGN folds to "k".
+ assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}Kk`);
+ assertBackrefMatch(`^${prefix}(.)\\1$`, `${prefix}\u212Ak`);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-derived-ctor-tdz-stack-trace.js b/deps/v8/test/mjsunit/regress/regress-derived-ctor-tdz-stack-trace.js
new file mode 100644
index 00000000000..bcfda170e42
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-derived-ctor-tdz-stack-trace.js
@@ -0,0 +1,42 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+class Base {}
+
+class DerivedBeforeSuper extends Base {
+ constructor() {
+ const stack = new Error().stack;
+ assertTrue(typeof stack === 'string' && stack.length > 0);
+ super();
+ }
+}
+
+class DerivedCapturedThis extends Base {
+ constructor() {
+ const capture = () => this;
+ const stack_before = new Error().stack;
+ assertTrue(typeof stack_before === 'string' && stack_before.length > 0);
+ super();
+ const stack_after = new Error().stack;
+ assertTrue(typeof stack_after === 'string' && stack_after.length > 0);
+ assertSame(this, capture());
+ }
+}
+
+function test() {
+ new DerivedBeforeSuper();
+ new DerivedCapturedThis();
+}
+
+%PrepareFunctionForOptimization(DerivedBeforeSuper);
+%PrepareFunctionForOptimization(DerivedCapturedThis);
+%PrepareFunctionForOptimization(test);
+test();
+test();
+%OptimizeFunctionOnNextCall(DerivedBeforeSuper);
+%OptimizeFunctionOnNextCall(DerivedCapturedThis);
+%OptimizeFunctionOnNextCall(test);
+test();
diff --git a/deps/v8/test/mjsunit/regress/regress-escaped-get-set-asi.js b/deps/v8/test/mjsunit/regress/regress-escaped-get-set-asi.js
new file mode 100644
index 00000000000..6d05a956388
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-escaped-get-set-asi.js
@@ -0,0 +1,21 @@
+// Copyright 2026 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.
+
+// Keep the class in a function to exercise preparsing as well as parsing.
+function createClass() {
+ return class {
+ g\u0065t
+ a;
+ s\u0065t
+ b;
+ static g\u0065t
+ c;
+ static s\u0065t
+ d;
+ };
+}
+
+const C = createClass();
+assertEquals(['get', 'a', 'set', 'b', 'c', 'd'], Object.keys(new C()));
+assertEquals(['get', 'set'], Object.keys(C));
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js
index a2ae1ce7349..fa86e210f17 100644
--- a/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js
@@ -17,8 +17,7 @@ function createNormalObject() {
}
%PrepareFunctionForOptimization(load);
for (let i = 0; i < 11; i++) {
- let o = (i % 2 === 0) ? createNormalObject()
- : d8.test.createSpecialObject({});
+ let o = createNormalObject();
o.a = i;
load(o);
}
@@ -41,8 +40,7 @@ function createNormalObject() {
}
%PrepareFunctionForOptimization(load);
for (let i = 0; i < 11; i++) {
- let o = (i % 2 === 0) ? createNormalObject()
- : d8.test.createSpecialObject({});
+ let o = createNormalObject();
o.a = i;
load(o);
}
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js
index 0a4717e4697..b0f9d8b8113 100644
--- a/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js
@@ -17,8 +17,7 @@ function createNormalObject() {
}
%PrepareFunctionForOptimization(load);
for (let i = 0; i < 11; i++) {
- let o = (i % 2 === 0) ? createNormalObject()
- : d8.test.createSpecialObject({});
+ let o = createNormalObject();
o.a = i;
load(o);
}
@@ -41,8 +40,7 @@ function createNormalObject() {
}
%PrepareFunctionForOptimization(load);
for (let i = 0; i < 11; i++) {
- let o = (i % 2 === 0) ? createNormalObject()
- : d8.test.createSpecialObject({});
+ let o = createNormalObject();
o.a = i;
load(o);
}
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js
index 7cc8d874695..bc4d07af67e 100644
--- a/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js
@@ -15,11 +15,10 @@ function load(o) {
}
%PrepareFunctionForOptimization(load);
-// Warm up with a mix of normal JS objects and API objects so that the LoadIC
-// enters HOMOMORPHIC state.
+// Warm up with normal JS objects which have the same shape but distinct maps
+// so that the LoadIC enters HOMOMORPHIC state.
for (let i = 0; i < 11; i++) {
- let o = (i % 2 === 0) ? createNormalObject()
- : d8.test.createSpecialObject({});
+ let o = createNormalObject();
o.a = i;
assertEquals(i, load(o));
}
diff --git a/deps/v8/test/mjsunit/regress/regress-json-escaped-key-transition.js b/deps/v8/test/mjsunit/regress/regress-json-escaped-key-transition.js
new file mode 100644
index 00000000000..e1b2421ff82
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-json-escaped-key-transition.js
@@ -0,0 +1,76 @@
+// Copyright 2026 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.
+
+// Regression test: JSON.parse must not match a hidden-class transition for an
+// escaped property key using the raw (undecoded) source bytes. The builder's
+// fast transition path compared `chars_ + key.start()` over `key.length()`
+// (the *decoded* length), so escaped keys (e.g. "\t", "\uXXXX") collapsed to
+// the byte 0x5C and matched a previously-seen "\\" key, making JSON.parse adopt
+// the wrong key. Transitions are isolate-global, so a prior parse corrupted a
+// later, unrelated parse.
+
+// A single-char escaped key must keep its decoded value even after a sibling
+// "\\" (backslash) key has been parsed on the same prefix map.
+(function TestEscapedKeyNotRenamedByPriorBackslashKey() {
+ function canaryKeys() {
+ return Object.keys(JSON.parse('{"\\r":1,"\\f":2}'));
+ }
+ assertArrayEquals(['\r', '\f'], canaryKeys());
+ // Plants a {<prefix>} -> "\" transition in the global transition tree.
+ JSON.parse('{"\\r":3,"\\\\":4}');
+ // Must be unaffected: "\f" stays U+000C, not U+005C.
+ assertArrayEquals(['\r', '\f'], canaryKeys());
+})();
+
+// Multi-character escaped key: decoded length 2 must not be compared against
+// the first two raw bytes ("\" + "r").
+(function TestMultiCharEscapedKey() {
+ function keys() {
+ return Object.keys(JSON.parse('{"\\t":1,"\\r\\r":2}'));
+ }
+ assertArrayEquals(['\t', '\r\r'], keys());
+ JSON.parse('{"\\t":1,"\\\\r":2}'); // plants the literal "\r" (0x5C 0x72) key
+ assertArrayEquals(['\t', '\r\r'], keys());
+})();
+
+// \uXXXX-escaped single-character key (here decodes to plain 'A').
+(function TestUnicodeEscapedKey() {
+ function keys() {
+ return Object.keys(JSON.parse('{"x":1,"\\u0041":2}'));
+ }
+ assertArrayEquals(['x', 'A'], keys());
+ JSON.parse('{"x":1,"\\\\":2}');
+ assertArrayEquals(['x', 'A'], keys());
+})();
+
+// Override/collide: an escaped key must not be renamed onto a real "\" sibling
+// and silently destroy a property (key count must be preserved).
+(function TestNoPropertyDestruction() {
+ // Prime the transition state that previously triggered the collapse.
+ JSON.parse('{"p":1,"\\\\":0}');
+ JSON.parse('{"p":1,"\\\\":0,"\\t":0}');
+ const o = JSON.parse('{"p":1,"\\t":"a","\\\\":"b"}');
+ assertEquals(3, Object.keys(o).length);
+ assertEquals('a', o['\t']);
+ assertEquals('b', o['\\']);
+})();
+
+// Self-contained single document: a later sibling object value must not be
+// corrupted by an earlier one within the same parse.
+(function TestNestedSiblingNotCorrupted() {
+ const o = JSON.parse(
+ '{"a":{"p":1,"\\\\":9},"b":{"p":1,"\\\\":"A","\\t":7},' +
+ '"c":{"p":1,"\\t":7,"\\\\":"B"}}');
+ assertEquals(3, Object.keys(o.c).length);
+ assertEquals(7, o.c['\t']);
+ assertEquals('B', o.c['\\']);
+})();
+
+// A plain (unescaped) empty key must still work (regression guard for the
+// empty-key_chars path the fix relies on).
+(function TestEmptyKeyStillWorks() {
+ const o = JSON.parse('{"a":1,"":2,"b":3}');
+ assertArrayEquals(['a', '', 'b'], Object.keys(o));
+ assertEquals(2, o['']);
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-maglev-mul-minus-zero.js b/deps/v8/test/mjsunit/regress/regress-maglev-mul-minus-zero.js
new file mode 100644
index 00000000000..455a06ab36b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-maglev-mul-minus-zero.js
@@ -0,0 +1,69 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --maglev
+
+// Maglev's Int32 constant folding of `*` must not turn a -0 product into +0.
+// Each case needs its own copy of the callee so that the `*` feedback stays
+// SignedSmall (a -0 result anywhere would widen it to Number and take the
+// Float64 path instead), which is what makes the multiply reach
+// TryFoldInt32BinaryOperation(int32_t, int32_t) with two constants.
+
+function makeMul(name) {
+ // The case name is interpolated so that each call compiles a distinct
+ // source string: identical sources hit the eval compilation cache, which
+ // would share one callee, and with it one feedback vector, across cases.
+ const src = `(function mul(a, b, stop) {
+ // ${name}
+ if (stop) return -Infinity;
+ return a * b;
+ })`;
+ const mul = eval(src);
+ %PrepareFunctionForOptimization(mul);
+ mul(2, 3, false); // SignedSmall feedback, product is not -0.
+ mul(2, 3, false);
+ return mul;
+}
+
+function check(name, x, y, expected) {
+ const mul = makeMul(name);
+ const f = new Function('stop', 'mul', `return 1 / mul(${x}, ${y}, stop);`);
+ %PrepareFunctionForOptimization(f);
+ f(true, mul); // Call-site feedback without executing the `*`.
+ f(true, mul);
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f(false, mul), name);
+}
+
+// -0 cases: 1 / -0 is -Infinity.
+check('-1 * 0', -1, 0, -Infinity);
+check('0 * -1', 0, -1, -Infinity);
+check('-3 * 0', -3, 0, -Infinity);
+check('INT32_MIN * 0', -2147483648, 0, -Infinity);
+check('0 * INT32_MIN', 0, -2147483648, -Infinity);
+
+// +0 products must still fold.
+check('3 * 0', 3, 0, Infinity);
+check('0 * 0', 0, 0, Infinity);
+
+function mulKeep(a, b, stop) {
+ if (stop) return -Infinity;
+ return a * b;
+}
+%PrepareFunctionForOptimization(mulKeep);
+mulKeep(2, 3, false);
+mulKeep(2, 3, false);
+
+// Non-zero product: folding is unaffected and no deopt should happen.
+function product(stop) {
+ const x = -3;
+ const y = -4;
+ return mulKeep(x, y, stop);
+}
+%PrepareFunctionForOptimization(product);
+product(true);
+product(true);
+%OptimizeMaglevOnNextCall(product);
+assertEquals(12, product(false));
+assertOptimized(product);
diff --git a/deps/v8/test/mjsunit/regress/regress-regexp-lookbehind-sort-alternatives.js b/deps/v8/test/mjsunit/regress/regress-regexp-lookbehind-sort-alternatives.js
new file mode 100644
index 00000000000..08eff84935f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-regexp-lookbehind-sort-alternatives.js
@@ -0,0 +1,22 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function test() {
+ assertEquals('ba', /(?<=(ba|a|c))x/.exec('bax')[1]);
+ assertEquals('cba', /(?<=(cba|ba|a|d))x/.exec('cbax')[1]);
+ assertTrue(/(?<=(ba|a|c))x\1/.test('baxba'));
+ assertFalse(/(?<=(ba|a|c))x\1$/.test('baxa'));
+
+ // the same capture case with /u, and /i
+ assertEquals('ba', /(?<=(ba|a|c))x/u.exec('bax')[1]);
+ assertEquals('ba', /(?<=(BA|a|c))x/i.exec('bax')[1]);
+
+ // replace
+ assertEquals('ba[ba]', 'bax'.replace(/(?<=(ba|a|c))x/, '[$1]'));
+
+ // Forward-mode factoring is unchanged
+ assertEquals('ab', /(?=(ab|a|c))/.exec('ab')[1]);
+}
+
+test();
diff --git a/deps/v8/test/mjsunit/regress/regression-513327211.js b/deps/v8/test/mjsunit/regress/regression-513327211.js
new file mode 100644
index 00000000000..dd7ea81a185
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regression-513327211.js
@@ -0,0 +1,52 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbofan
+
+// Regression test for 32-bit overflow-checked add/sub when the left operand
+// has dirty upper bits (e.g. a zero-extended uint32 value combined with a
+// 64-bit bitwise operation). If the overflow check assumes the operand is
+// already sign-extended, the overflow deopt is skipped and the optimized code
+// returns a wrapped int32 instead of the correct double.
+
+var arr = new Uint32Array([0x80000000]);
+
+// Immediate right operand.
+function addImm(i) { return (arr[i] ^ -1) + 1; }
+
+// Register right operand.
+function addReg(i, d) { return (arr[i] ^ -1) + d; }
+
+// Register right operand.
+function subReg(i, d) { return (arr[i] ^ 1) - d; }
+
+%PrepareFunctionForOptimization(addImm);
+for (let k = 0; k < 200000; k++) {
+ arr[0] = 0;
+ addImm(0);
+}
+arr[0] = 0x80000000;
+%OptimizeFunctionOnNextCall(addImm);
+assertEquals(2147483648, addImm(0));
+assertUnoptimized(addImm);
+
+%PrepareFunctionForOptimization(addReg);
+for (let k = 0; k < 200000; k++) {
+ arr[0] = 0;
+ addReg(0, 1);
+}
+arr[0] = 0x80000000;
+%OptimizeFunctionOnNextCall(addReg);
+assertEquals(2147483648, addReg(0, 1));
+assertUnoptimized(addReg);
+
+%PrepareFunctionForOptimization(subReg);
+for (let k = 0; k < 200000; k++) {
+ arr[0] = 0;
+ subReg(0, 2);
+}
+arr[0] = 0x80000000;
+%OptimizeFunctionOnNextCall(subReg);
+assertEquals(-2147483649, subReg(0, 2));
+assertUnoptimized(subReg);
diff --git a/deps/v8/test/mjsunit/regress/regression-514440066.js b/deps/v8/test/mjsunit/regress/regression-514440066.js
new file mode 100644
index 00000000000..208f933b610
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regression-514440066.js
@@ -0,0 +1,32 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbofan
+
+// Regression test for a miscompile of a Word32And followed by a comparison
+// against zero. A 32-bit value is not guaranteed to be sign-extended in its
+// 64-bit register: a zero-extending Uint32 load followed by a Word32Xor with -1
+// can leave the upper 32 bits set. If the zero test is performed on the full
+// register width, those dirty upper bits make a zero i32 result look non-zero
+// and invert the branch. The 32-bit zero test must normalize the result first.
+
+var arr = new Uint32Array([0x55555555, 0xAAAAAAAA]);
+
+function andZero(i, j) {
+ var a = arr[i] ^ -1;
+ var b = arr[j] ^ -1;
+ // (~a & ~b) === 0, since ~a & ~b == ~(a | b) == ~0xFFFFFFFF == 0 (i32).
+ return (a & b) === 0;
+}
+
+%PrepareFunctionForOptimization(andZero);
+for (let k = 0; k < 200000; k++) {
+ arr[0] = 0xFFFFFFFF;
+ arr[1] = 0x00000000;
+ andZero(0, 1);
+}
+arr[0] = 0x55555555;
+arr[1] = 0xAAAAAAAA;
+%OptimizeFunctionOnNextCall(andZero);
+assertEquals(true, andZero(0, 1));
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-334687959.js b/deps/v8/test/mjsunit/regress/wasm/regress-334687959.js
index 2138bb6e433..acbd2303ec5 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-334687959.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-334687959.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --wasm-inlining --wasm-tiering-budget=1
+// Flags: --wasm-inlining --wasm-tiering-budget=1 --wasm-tier-up
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-368086282.js b/deps/v8/test/mjsunit/regress/wasm/regress-368086282.js
index e04cf40575d..05c8547cbf5 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-368086282.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-368086282.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --turbo-fast-api-calls --expose-fast-api --wasm-fast-api
+// Flags: --turbo-fast-api-calls --expose-fast-api --wasm-fast-api --turbofan
// Flags: --wasm-lazy-compilation --wasm-unsafe-fast-api-wrapper
// Flags: --fast-api-allow-float-in-sim --allow-natives-syntax
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-438770394.js b/deps/v8/test/mjsunit/regress/wasm/regress-438770394.js
index 08e0990782d..18770b18b87 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-438770394.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-438770394.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --turbo-fast-api-calls --expose-fast-api --wasm-fast-api
+// Flags: --turbo-fast-api-calls --expose-fast-api --wasm-fast-api --turbofan
// Flags: --wasm-lazy-compilation
// Flags: --fast-api-allow-float-in-sim
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-523591366.js b/deps/v8/test/mjsunit/regress/wasm/regress-523591366.js
new file mode 100644
index 00000000000..534fcf7410f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-523591366.js
@@ -0,0 +1,85 @@
+// Copyright 2026 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.
+
+// Flags: --liftoff
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// 32769 pages * 64 KiB = 0x8001_0000 bytes (just over 2 GiB).
+// Shared memory32 reserves the full max, so this is a virtual reservation.
+const kPages = 32769;
+const memory = new WebAssembly.Memory(
+ {initial: kPages, maximum: kPages, shared: true});
+
+const builder = new WasmModuleBuilder();
+builder.addImportedMemory('m', 'memory', kPages, kPages, 'shared');
+
+builder.addFunction('probe',
+ makeSig([kWasmI32, kWasmI32], [kWasmI32]))
+ .addBody([
+ kExprLocalGet, 0, // index (i32)
+ kExprLocalGet, 1, // expected (i32)
+ kExprI64Const, 0, // timeout = 0 ns -> never blocks
+ kAtomicPrefix, kExprI32AtomicWait, /*align=*/2, /*offset=*/0,
+ ])
+ .exportFunc();
+
+builder.addFunction('probe_offset',
+ makeSig([kWasmI32, kWasmI32], [kWasmI32]))
+ .addBody([
+ kExprLocalGet, 0, // index (i32)
+ kExprLocalGet, 1, // expected (i32)
+ kExprI64Const, 0, // timeout = 0 ns -> never blocks
+ kAtomicPrefix, kExprI32AtomicWait, /*align=*/2, /*offset=*/4,
+ ])
+ .exportFunc();
+
+builder.addFunction('probe64',
+ makeSig([kWasmI32, kWasmI64], [kWasmI32]))
+ .addBody([
+ kExprLocalGet, 0, // index (i32)
+ kExprLocalGet, 1, // expected (i64)
+ kExprI64Const, 0, // timeout = 0 ns -> never blocks
+ kAtomicPrefix, kExprI64AtomicWait, /*align=*/3, /*offset=*/0,
+ ])
+ .exportFunc();
+
+builder.addFunction('probe64_offset',
+ makeSig([kWasmI32, kWasmI64], [kWasmI32]))
+ .addBody([
+ kExprLocalGet, 0, // index (i32)
+ kExprLocalGet, 1, // expected (i64)
+ kExprI64Const, 0, // timeout = 0 ns -> never blocks
+ kAtomicPrefix, kExprI64AtomicWait, /*align=*/3, /*offset=*/8,
+ ])
+ .exportFunc();
+
+const instance = builder.instantiate({m: {memory: memory}});
+
+// Test boundary index values:
+// 1. Minimum index 0 (within Smi range).
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe(0, 0));
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe64(0, 0n));
+
+// 2. Crossing the 2 GiB boundary via non-zero immediate offset:
+// 0x7ffffffc + 4 = 0x80000000
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe_offset(0x7ffffffc | 0, 0));
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe64_offset(0x7ffffff8 | 0, 0n));
+
+// 3. Index at >= 2 GiB (0x80000000):
+// On 64-bit architectures, Liftoff must zero-extend the 32-bit index when
+// passing it as pointer-sized offset to the AtomicWait builtin, rather than
+// sign-extending it to 0xFFFF_FFFF_8000_0000.
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe(0x80000000 | 0, 0));
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe64(0x80000000 | 0, 0n));
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe_offset(0x80000000 | 0, 0));
+assertEquals(kAtomicWaitTimedOut, instance.exports.probe64_offset(0x80000000 | 0, 0n));
+
+// 4. Out-of-bounds index (0x80010000 >= memory size):
+// Assert that bounds checking remains intact after zero-extension and pointer
+// math refactoring.
+assertTraps(kTrapMemOutOfBounds, () => instance.exports.probe(0x80010000 | 0, 0));
+assertTraps(kTrapMemOutOfBounds, () => instance.exports.probe64(0x80010000 | 0, 0n));
+assertTraps(kTrapMemOutOfBounds, () => instance.exports.probe_offset(0x80010000 | 0, 0));
+assertTraps(kTrapMemOutOfBounds, () => instance.exports.probe64_offset(0x80010000 | 0, 0n));
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-557846268.js b/deps/v8/test/mjsunit/regress/wasm/regress-557846268.js
new file mode 100644
index 00000000000..0720310c271
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-557846268.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-wasmfx --trace-wasm --no-wasm-lazy-compilation
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+let builder = new WasmModuleBuilder();
+let sig_v_v = builder.addType(kSig_v_v);
+let cont_v_v = builder.addCont(sig_v_v);
+let sig_v_c = builder.addType(makeSig([], [wasmRefNullType(cont_v_v)]));
+let tag = builder.addTag(kSig_v_v);
+
+let dummy = builder.addFunction("dummy", sig_v_v).addBody([
+]).exportFunc();
+let get_cont = builder.addFunction("get_cont", makeSig([], [wasmRefType(cont_v_v)]))
+ .addBody([
+ kExprRefFunc, dummy.index,
+ kExprContNew, cont_v_v,
+ ]).exportFunc();
+
+let body = [
+ kExprCallFunction, get_cont.index,
+ kExprResume, ...wasmUnsignedLeb(cont_v_v), ...wasmUnsignedLeb(1),
+ 0x00, ...wasmUnsignedLeb(tag), 0x00,
+ kExprRefNull, cont_v_v,
+];
+builder.addFunction("main", sig_v_c)
+ .addBody(body).exportFunc();
+let instance = builder.instantiate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-561660149.js b/deps/v8/test/mjsunit/regress/wasm/regress-561660149.js
new file mode 100644
index 00000000000..eba91e86781
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-561660149.js
@@ -0,0 +1,75 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --stack-size=100
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+const array_type = builder.addArray(kWasmExternRef, {mutable: true});
+
+const kNumParamsA = 50;
+const sigA = makeSig(new Array(kNumParamsA).fill(kWasmI64), []);
+const funcA = builder.addFunction('A', sigA).addBody([]);
+
+const sigBC = makeSig([kWasmI32, wasmRefNullType(array_type)], []);
+
+const bodyB = [];
+for (let i = 0; i < kNumParamsA; i++) {
+ bodyB.push(...wasmI64Const(0x414141414141n));
+}
+bodyB.push(kExprCallFunction, funcA.index);
+builder.addFunction('B', sigBC).addBody(bodyB).exportFunc();
+
+const kNumParamsBig = 600;
+const sigBig = makeSig(new Array(kNumParamsBig).fill(kWasmI64), []);
+const funcBig = builder.addFunction('Big', sigBig).addBody([]);
+
+const kNumArrayFills = 15;
+const bodyC = [
+ kExprLocalGet, 0,
+ kExprI32Eqz,
+ kExprIf, kWasmVoid,
+];
+for (let i = 0; i < kNumArrayFills; i++) {
+ bodyC.push(
+ kExprLocalGet, 1,
+ kExprI32Const, 0,
+ kExprRefNull, kExternRefCode,
+ kExprI32Const, 32,
+ kGCPrefix, kExprArrayFill, array_type
+ );
+}
+for (let i = 0; i < kNumParamsBig; i++) {
+ bodyC.push(...wasmI64Const(0n));
+}
+bodyC.push(
+ kExprCallFunction, funcBig.index,
+ kExprEnd
+);
+
+builder.addFunction('C', sigBC)
+ .addBody(bodyC)
+ .exportFunc();
+
+const instance = builder.instantiate();
+const B = instance.exports.B;
+const C = instance.exports.C;
+
+%WasmTierUpFunction(B);
+%WasmTierUpFunction(C);
+Error.stackTraceLimit = 0;
+
+function recurse() {
+ try {
+ B(1, null);
+ recurse();
+ } catch (e) {
+ B(1, null);
+ %SimulateNewspaceFull();
+ C(1, null);
+ }
+}
+
+recurse();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-561662099.js b/deps/v8/test/mjsunit/regress/wasm/regress-561662099.js
new file mode 100644
index 00000000000..f736de31151
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-561662099.js
@@ -0,0 +1,46 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-custom-descriptors --no-liftoff --no-wasm-inlining
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+const builder = new WasmModuleBuilder();
+builder.startRecGroup();
+let $struct1 = builder.nextTypeIndex() + 1;
+let $struct0 = builder.addStruct({fields: [], final: true, descriptor: $struct1});
+/* $struct1 */ builder.addStruct({fields: [], final: true, describes: $struct0});
+builder.endRecGroup();
+
+let $tag = builder.addTag(makeSig([wasmRefType($struct1)], []));
+
+builder.addFunction("thrower", kSig_v_v)
+ .addBody([
+ kGCPrefix, kExprStructNewDefault, $struct1,
+ kExprThrow, $tag,
+ ]);
+
+builder.addFunction("main", kSig_v_v).exportFunc()
+ .addLocals(wasmRefType($struct1), 1)
+ .addBody([
+ kExprBlock, kWasmRef, $struct1,
+ kExprTryTable, kWasmVoid, 1,
+ kCatchNoRef, $tag, 0,
+ kExprCallFunction, 0,
+ kExprEnd,
+ kExprUnreachable,
+ kExprEnd,
+ kExprLocalSet, 0,
+
+ kExprLoop, kWasmVoid,
+ kExprLocalGet, 0,
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCastDescEq, $struct0,
+ kExprDrop,
+ kExprBr, 0,
+ kExprEnd,
+ ]);
+
+const instance = builder.instantiate();
+assertThrows(() => instance.exports.main(), WebAssembly.RuntimeError, /illegal cast/);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-562655126.js b/deps/v8/test/mjsunit/regress/wasm/regress-562655126.js
new file mode 100644
index 00000000000..3e99d5983b4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-562655126.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --turboshaft-verify-load-elimination
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+let builder = new WasmModuleBuilder();
+
+let kSig_i_ri = makeSig([kWasmExternRef, kWasmI32], [kWasmI32]);
+let charCodeAt = builder.addImport("wasm:js-string", "charCodeAt", kSig_i_ri);
+
+builder.addFunction("main", kSig_i_r)
+ .addBody([
+ kExprLocalGet, 0,
+ kExprRefAsNonNull,
+ kExprI32Const, 0,
+ kExprCallFunction, charCodeAt,
+
+ kExprLocalGet, 0,
+ kExprI32Const, 0,
+ kExprCallFunction, charCodeAt,
+
+ kExprI32Add,
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate({}, { builtins: ["js-string"] });
+instance.exports.main("abcd");
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-563427048-2.js b/deps/v8/test/mjsunit/regress/wasm/regress-563427048-2.js
new file mode 100644
index 00000000000..1c01e286dfb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-563427048-2.js
@@ -0,0 +1,36 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-custom-descriptors --allow-natives-syntax
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.startRecGroup();
+let $struct1 = builder.nextTypeIndex() + 1;
+let $struct0 = builder.addStruct({fields: [], final: true, descriptor: $struct1});
+/* $struct1 */ builder.addStruct({fields: [], final: true, describes: $struct0});
+let $struct2 = builder.nextTypeIndex();
+let $struct3 = builder.nextTypeIndex() + 1;
+/* $struct2 */ builder.addStruct({fields: [], descriptor: $struct3});
+/* $struct3 */ builder.addStruct({fields: [], describes: $struct2});
+builder.endRecGroup();
+
+let w8 = builder.addFunction(undefined, kSig_v_v).exportAs('w8')
+ .addBody([
+ kExprBlock, kWasmRefNull, $struct0,
+ kGCPrefix, kExprStructNewDefault, $struct3,
+ kGCPrefix, kExprStructNewDefault, $struct1,
+ kGCPrefix, kExprBrOnCastDescEq,
+ 0b11 /* nullable -> nullable */, 0, kAnyRefCode, kWasmExact, $struct0,
+ kExprDrop,
+ kExprRefNull, kWasmExact, $struct0,
+ kExprEnd,
+ kExprDrop,
+ ]);
+
+const instance = builder.instantiate();
+instance.exports.w8();
+%WasmTierUpFunction(instance.exports.w8);
+instance.exports.w8();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-563427048-3.js b/deps/v8/test/mjsunit/regress/wasm/regress-563427048-3.js
new file mode 100644
index 00000000000..4c225fb00a4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-563427048-3.js
@@ -0,0 +1,33 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-custom-descriptors
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.startRecGroup();
+let $struct1 = builder.nextTypeIndex() + 1;
+let $struct0 = builder.addStruct({fields: [], descriptor: $struct1});
+let $struct2 = builder.nextTypeIndex() + 1;
+/* $struct1 */ builder.addStruct({fields: [], descriptor: $struct2, describes: $struct0});
+let $struct3 = builder.nextTypeIndex() + 1;
+/* $struct2 */ builder.addStruct({fields: [], descriptor: $struct3, describes: $struct1});
+/* $struct3 */ builder.addStruct({fields: [], describes: $struct2});
+builder.endRecGroup();
+
+builder.addFunction('func_80_invoker', kSig_v_v).exportFunc()
+ .addBody([
+ kGCPrefix, kExprStructNewDefault, $struct3,
+ kGCPrefix, kExprStructNewDefaultDesc, $struct2,
+ kGCPrefix, kExprStructNewDefaultDesc, $struct1,
+ kGCPrefix, kExprRefGetDesc, $struct1,
+ kGCPrefix, kExprStructNewDefault, $struct3,
+ kGCPrefix, kExprRefCastDescEq, kWasmExact, $struct2,
+ kExprUnreachable,
+ ]);
+
+const instance = builder.instantiate({});
+assertThrows(() => instance.exports.func_80_invoker(), WebAssembly.RuntimeError,
+ /illegal cast/);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-563427048.js b/deps/v8/test/mjsunit/regress/wasm/regress-563427048.js
new file mode 100644
index 00000000000..deb2fc1af50
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-563427048.js
@@ -0,0 +1,50 @@
+// Copyright 2026 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.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+let $sig0 = builder.addType(kSig_v_v);
+let $sig1 = builder.addType(makeSig([], [kWasmExnRef]));
+let $sig2 = builder.addType(makeSig([kWasmF32, kWasmI32, kWasmI32], [kWasmFuncRef, kWasmStructRef, kWasmNullExnRef, kWasmF32]));
+let w0 = builder.addFunction(undefined, kSig_v_v).exportAs('w0');
+builder.addStart(w0.index);
+
+w0.addLocals(kWasmNullRef, 1) // $var1
+ .addLocals(kWasmF32, 1) // $var3
+ .addLocals(kWasmNullExnRef, 4) // $var4
+ .addBody([
+ kExprRefNull, kNullRefCode,
+ kExprLocalSet, 0, // $var1
+ kExprI32Const, 0,
+ kExprF32ReinterpretI32,
+ kExprLocalSet, 1,
+ kExprBlock, $sig1,
+ kExprLocalGet, 1,
+ ...wasmI32Const(-2075409857),
+ kExprRefNull, kNullRefCode,
+ kGCPrefix, kExprRefTest, kArrayRefCode,
+ kExprTryTable, $sig2, 1,
+ kCatchAllRef, 0,
+ kExprDrop,
+ kExprDrop,
+ kExprDrop,
+ kExprRefNull, kExnRefCode,
+ kExprThrowRef,
+ kExprRefNull, kFuncRefCode,
+ kExprRefNull, kNullRefCode,
+ kExprRefNull, kNullExnRefCode,
+ kExprLocalGet, 1,
+ kExprEnd,
+ kExprDrop,
+ kExprLocalSet, 2,
+ kExprDrop,
+ kExprDrop,
+ kExprLocalGet, 2,
+ kExprEnd,
+ kGCPrefix, kExprRefCastNull, kNullExnRefCode,
+ kExprDrop,
+ ]);
+
+assertThrows(() => builder.instantiate(), WebAssembly.RuntimeError);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-565565747.js b/deps/v8/test/mjsunit/regress/wasm/regress-565565747.js
new file mode 100644
index 00000000000..25704b71875
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-565565747.js
@@ -0,0 +1,23 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-shared
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+let struct_type = builder.addStruct({fields: [makeField(kWasmI32, true)],
+ shared: true});
+builder.addFunction('make_struct', makeSig([], [wasmRefType(struct_type)]))
+ .addBody([kExprI32Const, 42, kGCPrefix, kExprStructNew, struct_type])
+ .exportFunc();
+let instance = builder.instantiate();
+let shared_struct = instance.exports.make_struct();
+let mem = new WebAssembly.Memory({initial: 1, maximum: 2, shared: true});
+let wasm_sab = mem.buffer;
+let regular_sab = new SharedArrayBuffer();
+let w = new Worker('onmessage = function(e) { postMessage(1); };',
+ {type: 'string'});
+w.postMessage([shared_struct, wasm_sab, regular_sab, mem]);
+w.getMessage();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-565847635.js b/deps/v8/test/mjsunit/regress/wasm/regress-565847635.js
new file mode 100644
index 00000000000..7e5955eb465
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-565847635.js
@@ -0,0 +1,27 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-fp16 --no-enable-avx2
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+builder.addMemory(1, 1);
+builder.addFunction('test_store', kSig_v_f)
+ .addBody([
+ wasmI32Const(0),
+ kExprLocalGet, 0,
+ kNumericPrefix, kExprF32StoreF16, 0, 0,
+ ].flat())
+ .exportFunc();
+builder.addFunction('test_load', kSig_f_v)
+ .addBody([
+ wasmI32Const(0),
+ kNumericPrefix, kExprF32LoadF16, 0, 0,
+ ].flat())
+ .exportFunc();
+
+let instance = builder.instantiate();
+instance.exports.test_store(1.5);
+assertEquals(1.5, instance.exports.test_load());
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-566973959.js b/deps/v8/test/mjsunit/regress/wasm/regress-566973959.js
new file mode 100644
index 00000000000..8fb1172f923
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-566973959.js
@@ -0,0 +1,27 @@
+// Copyright 2026 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.
+
+const kPageSize = 65536;
+const memory = new WebAssembly.Memory({initial: 1, maximum: 4, shared: true});
+const gsab = memory.toResizableBuffer();
+memory.toFixedLengthBuffer(); // gsab is no longer the primary buffer.
+
+const worker = new Worker(function() {
+ onmessage = function({data}) {
+ try {
+ data.gsab.grow(data.pages * 65536);
+ postMessage(data.gsab.byteLength);
+ } catch (e) {
+ postMessage(`${e.name}: ${e.message}`);
+ }
+ };
+}, {type: 'function'});
+
+worker.postMessage({mem: memory, gsab: gsab, pages: 2});
+assertEquals(2 * kPageSize, worker.getMessage());
+assertEquals(2 * kPageSize, gsab.byteLength);
+
+worker.postMessage({gsab: gsab, pages: 3});
+assertEquals(3 * kPageSize, worker.getMessage());
+assertEquals(3 * kPageSize, gsab.byteLength);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-528884838.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-528884838.js
index 1acb742cfbf..6625662aacc 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-simd-528884838.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-528884838.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --experimental-wasm-revectorize --allow-natives-syntax
+// Flags: --wasm-revectorize --allow-natives-syntax
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-wasmfx-unreachable-resume.js b/deps/v8/test/mjsunit/regress/wasm/regress-wasmfx-unreachable-resume.js
new file mode 100644
index 00000000000..4b0f2807eed
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-wasmfx-unreachable-resume.js
@@ -0,0 +1,51 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-wasmfx --no-liftoff
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+let builder = new WasmModuleBuilder();
+let sig_v_v = builder.addType(kSig_v_v);
+let cont_v_v = builder.addCont(sig_v_v);
+let tag = builder.addTag(kSig_v_v);
+
+// Not inlinable, and emitted after the block below becomes reachable again.
+let imported = builder.addImport("m", "f", kSig_v_v);
+
+let dummy = builder.addFunction("dummy", sig_v_v).addBody([]).exportFunc();
+
+// Never returns, so after inlining its return block has no predecessors and the
+// assembler keeps generating unreachable operations, while the wasm decoder
+// still considers the following code reachable.
+let never_returns =
+ builder.addFunction("never_returns", sig_v_v).addBody([kExprUnreachable]);
+
+let get_cont =
+ builder.addFunction("get_cont", makeSig([], [wasmRefType(cont_v_v)]))
+ .addBody([
+ kExprRefFunc, dummy.index,
+ kExprContNew, cont_v_v,
+ ]);
+
+builder.addFunction("main", kSig_v_i)
+ .addBody([
+ kExprBlock, kWasmVoid,
+ // Gives the end of the block a reachable predecessor.
+ kExprLocalGet, 0,
+ kExprBrIf, 0,
+ kExprCallFunction, never_returns.index,
+ kExprBlock, kWasmRefNull, cont_v_v,
+ kExprCallFunction, get_cont.index,
+ kExprResume, cont_v_v, 1, kOnSuspend, tag, 0,
+ kExprRefNull, cont_v_v,
+ kExprEnd,
+ kExprDrop,
+ kExprEnd,
+ kExprCallFunction, imported,
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate({m: {f: () => {}}});
+instance.exports.main(1);
diff --git a/deps/v8/test/mjsunit/sandbox/memory-corruption-api.js b/deps/v8/test/mjsunit/sandbox/memory-corruption-api.js
index 721eef21625..d42ebe97bb2 100644
--- a/deps/v8/test/mjsunit/sandbox/memory-corruption-api.js
+++ b/deps/v8/test/mjsunit/sandbox/memory-corruption-api.js
@@ -8,6 +8,7 @@ const kHeapObjectTag = 0x1;
assertSame(typeof Sandbox.base, 'number');
assertSame(typeof Sandbox.byteLength, 'number');
+assertSame(typeof Sandbox.getMetadata().trustedPointerHandleShift, 'number');
function getBuiltinId(name) {
return Sandbox.getBuiltinNames().indexOf(name);
diff --git a/deps/v8/test/mjsunit/sandbox/regress-435630461.js b/deps/v8/test/mjsunit/sandbox/regress-435630461.js
index f42fe88c955..d11af2e464c 100644
--- a/deps/v8/test/mjsunit/sandbox/regress-435630461.js
+++ b/deps/v8/test/mjsunit/sandbox/regress-435630461.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --sandbox-testing
+// Flags: --sandbox-testing --mock-arraybuffer-allocator
const kHeapObjectTag = 1;
const kSandboxedPointerShift = 24n;
diff --git a/deps/v8/test/mjsunit/sandbox/regress-561387542.js b/deps/v8/test/mjsunit/sandbox/regress-561387542.js
new file mode 100644
index 00000000000..ad17ca49b28
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-561387542.js
@@ -0,0 +1,46 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing --cache=after-execute
+
+function outer() {
+ function inner() {
+ return 42;
+ }
+ return inner;
+}
+
+const innerFunc = outer();
+
+const wasmTable = new WebAssembly.Table({ initial: 2, element: "anyfunc" });
+
+const wasmBytes = new Uint8Array([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, // wasm magic & version
+ 0x01, 0x04, 0x01, 0x60, 0x00, 0x00, // type section: () -> ()
+ 0x03, 0x02, 0x01, 0x00, // func section
+ 0x07, 0x05, 0x01, 0x01, 0x66, 0x00, 0x00, // export section: export "f"
+ 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b // code section: empty function
+]);
+const wasmModule = new WebAssembly.Module(wasmBytes);
+const wasmInstance = new WebAssembly.Instance(wasmModule);
+const wasmExportedFunc = wasmInstance.exports.f;
+
+const sandboxMemory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+
+const tableAddress = Sandbox.getAddressOf(wasmTable);
+const wasmDispatchTableHandle = sandboxMemory.getUint32(tableAddress + 28, true);
+
+const funcAddress = Sandbox.getAddressOf(innerFunc);
+const funcSfiAddress = sandboxMemory.getUint32(funcAddress + 16, true) - 1;
+const currentTrustedHandle = sandboxMemory.getUint32(funcSfiAddress + 4, true);
+
+const scriptAddress = sandboxMemory.getUint32(funcSfiAddress + 20, true) - 1;
+const isDeserialized = (sandboxMemory.getUint32(scriptAddress + 56, true) & 0x1000) !== 0;
+
+if (!isDeserialized) {
+ sandboxMemory.setUint32(funcSfiAddress + 4, wasmDispatchTableHandle, true);
+} else {
+ sandboxMemory.setUint32(tableAddress + 28, currentTrustedHandle, true);
+ wasmTable.set(0, wasmExportedFunc);
+}
diff --git a/deps/v8/test/mjsunit/sandbox/regress-562788806.js b/deps/v8/test/mjsunit/sandbox/regress-562788806.js
new file mode 100644
index 00000000000..5050cfbdc9f
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-562788806.js
@@ -0,0 +1,34 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing --cache=after-execute --always-sparkplug --sparkplug
+
+const mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+const sfi = Sandbox.dereferenceTaggedPointerField(
+ function() {}, 'shared_function_info');
+const script = Sandbox.dereferenceTaggedPointerField(sfi, 'script');
+const scriptAddr = Sandbox.getAddressOf(script);
+
+const params = Array.from({length: 3328}, (_, i) => 'p' + i).join(',');
+(0, eval)(
+ `function foo(${params}) { (() => new.target)(); p0.a; p0.b; v0 = 0; ` +
+ `return 65535; var [v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13] = []; }`);
+foo({a: 1, b: 2});
+
+const fooAddr = Sandbox.getAddressOf(foo);
+const kWrappedArgumentsOffset = 36;
+const kFeedbackCellOffset = 24;
+const kDispatchHandleOffset = 12;
+
+const existing = mem.getUint32(scriptAddr + kWrappedArgumentsOffset, true);
+if (existing !== 0x11) {
+ const cellAddr = (existing & ~3) >>> 0;
+ const corruptedHandle = mem.getUint32(cellAddr + 8, true);
+ mem.setUint32(fooAddr + kDispatchHandleOffset, corruptedHandle, true);
+ foo();
+} else {
+ const fbCellAddr = mem.getUint32(fooAddr + kFeedbackCellOffset, true);
+ mem.setUint32((fbCellAddr & ~3) + 4, 0x11, true);
+ mem.setUint32(scriptAddr + kWrappedArgumentsOffset, fbCellAddr, true);
+}
diff --git a/deps/v8/test/mjsunit/sandbox/regress-565797753.js b/deps/v8/test/mjsunit/sandbox/regress-565797753.js
new file mode 100644
index 00000000000..820dd461c71
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-565797753.js
@@ -0,0 +1,30 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing
+
+let memory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+
+// Create two direct sequential one-byte strings
+let s1 = JSON.parse('"' + 'A'.repeat(100) + '"');
+let s2 = JSON.parse('"' + 'B'.repeat(100) + '"');
+
+// Concatenate them to create a ConsString whose halves are both direct (SeqOneByteString)
+let cons = s1 + s2;
+
+// Create a SlicedString
+let base_str = JSON.parse('"' + 'C'.repeat(100) + '"');
+let slice = base_str.substring(0, 50);
+
+let slice_addr = Sandbox.getAddressOf(slice);
+let cons_addr = Sandbox.getAddressOf(cons);
+
+// Overwrite slice.parent_ with cons (tagged pointer)
+memory.setUint32(slice_addr + 12, cons_addr | 1, true);
+
+// Overwrite slice.length_ with 10 (length < cons.first length of 100)
+memory.setUint32(slice_addr + 8, 10, true);
+
+// Trigger StringTable::TryStringToIndexOrLookupExisting via Object.prototype.hasOwnProperty
+Object.prototype.hasOwnProperty.call({}, slice);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js b/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js
index 85bd9a8217a..f2390bd6682 100644
--- a/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js
@@ -20,7 +20,7 @@ function load(o) {
%EnsureFeedbackVectorForFunction(load);
%NeverOptimizeFunction(load);
-for (let i = 0; i < 11; i++) {
+for (let i = 0; i < 10; i++) {
let o = {x: 42};
o['p' + i] = i;
load(o);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-532513886.js b/deps/v8/test/mjsunit/sandbox/regress/regress-532513886.js
new file mode 100644
index 00000000000..7905d46f4ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-532513886.js
@@ -0,0 +1,36 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --sandbox-testing --turbolev
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const memory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+const kJSFunctionType = Sandbox.getInstanceTypeIdFor('JS_FUNCTION_TYPE');
+const kDispatchHandleOffset =
+ Sandbox.getFieldOffset(kJSFunctionType, 'dispatch_handle');
+
+const builder = new WasmModuleBuilder();
+builder.addFunction('w0', kSig_v_i)
+ .addBody([])
+ .exportFunc();
+const instance = builder.instantiate();
+const w0 = instance.exports.w0;
+
+function caller(x) {
+ w0(x);
+}
+
+%PrepareFunctionForOptimization(caller);
+caller(0);
+
+const math_sin_addr = Sandbox.getAddressOf(Math.sin);
+const math_sin_handle =
+ memory.getUint32(math_sin_addr + kDispatchHandleOffset, true);
+
+const w0_addr = Sandbox.getAddressOf(w0);
+memory.setUint32(w0_addr + kDispatchHandleOffset, math_sin_handle, true);
+
+%OptimizeFunctionOnNextCall(caller);
+caller(0);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-560282287-2.js b/deps/v8/test/mjsunit/sandbox/regress/regress-560282287-2.js
new file mode 100644
index 00000000000..3bda1ccba24
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-560282287-2.js
@@ -0,0 +1,87 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const memory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+const getField = (obj, offset) => memory.getUint32(obj + offset, true);
+const setField = (obj, offset, value) =>
+ memory.setUint32(obj + offset, value, true);
+
+const kTrustedPointerHandleShift =
+ Sandbox.getMetadata().trustedPointerHandleShift;
+const kTrustedPointerHandleStride = 1 << kTrustedPointerHandleShift;
+
+const builder = new WasmModuleBuilder();
+const structType = builder.addStruct([
+ makeField(kWasmI64, true),
+ makeField(kWasmI64, true),
+ makeField(kWasmI64, true),
+]);
+const arrType = builder.addArray(kWasmI32);
+const sig = builder.addType(kSig_v_v);
+
+const importedLen = builder.addImportedGlobal('m', 'len', kWasmI32, false);
+const target = builder.addFunction('target', sig).addBody([
+ kExprGlobalGet, 3,
+ ...wasmI64Const(0x41414141),
+ kGCPrefix, kExprStructSet, structType, 2,
+]).exportFunc();
+
+// Global 1 evaluates (ref.func $target), allocating a WasmInternalFunction
+// whose protected_implicit_arg points to the new WasmTrustedInstanceData.
+builder.addGlobal(wasmRefType(sig), false, false, [
+ kExprRefFunc, target.index,
+]);
+// Global 2 traps when importedLen == 0x7fffffff, aborting InitGlobals before
+// Global 3 (a non-nullable struct reference) is initialized.
+builder.addGlobal(wasmRefType(arrType), false, false, [
+ kExprGlobalGet, importedLen,
+ kGCPrefix, kExprArrayNewDefault, arrType,
+]);
+builder.addGlobal(wasmRefType(structType), false, false, [
+ kGCPrefix, kExprStructNewDefault, structType,
+]);
+
+const table = builder.addTable(wasmRefNullType(sig), 1, 1).exportAs('table');
+builder.addActiveElementSegment(
+ table.index, wasmI32Const(0), [[kExprRefFunc, target.index]],
+ wasmRefNullType(sig));
+builder.addFunction('invoker', sig).addBody([
+ kExprI32Const, 0,
+ kExprTableGet, table.index,
+ kExprCallRef, sig,
+]).exportFunc();
+
+const module = builder.toModule();
+const good = new WebAssembly.Instance(module, {m: {len: 0}});
+const tableAddr = Sandbox.getAddressOf(good.exports.table);
+const entriesOffset = Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdOf(good.exports.table), 'entries');
+const entriesAddr = getField(tableAddr, entriesOffset) - 1;
+const funcRefAddr = getField(entriesAddr, 8) - 1;
+const trustedInternalOffset = Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdOfObjectAt(funcRefAddr), 'trusted_internal');
+const beforeHandle = getField(funcRefAddr, trustedInternalOffset);
+
+assertThrows(
+ () => new WebAssembly.Instance(module, {m: {len: 0x7fffffff}}),
+ WebAssembly.RuntimeError);
+
+const after = new WebAssembly.Instance(module, {m: {len: 0}});
+const afterEntriesAddr =
+ getField(Sandbox.getAddressOf(after.exports.table), entriesOffset) - 1;
+const afterFuncRefAddr = getField(afterEntriesAddr, 8) - 1;
+const afterHandle = getField(afterFuncRefAddr, trustedInternalOffset);
+
+// Target the WasmInternalFunction handle allocated during the failed instance's
+// InitGlobals (the 3rd trusted handle allocated per instantiation, after
+// WasmTrustedInstanceData and WasmDispatchTable).
+const failedInternalFuncHandle =
+ afterHandle - 3 * kTrustedPointerHandleStride;
+assertTrue(failedInternalFuncHandle > beforeHandle);
+setField(funcRefAddr, trustedInternalOffset, failedInternalFuncHandle);
+good.exports.invoker();
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-560282287.js b/deps/v8/test/mjsunit/sandbox/regress/regress-560282287.js
new file mode 100644
index 00000000000..9f716aace11
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-560282287.js
@@ -0,0 +1,62 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const memory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+const getField = (obj, offset) => memory.getUint32(obj + offset, true);
+const setField = (obj, offset, value) =>
+ memory.setUint32(obj + offset, value, true);
+
+const kTrustedPointerHandleShift =
+ Sandbox.getMetadata().trustedPointerHandleShift;
+const kTrustedPointerHandleStride = 1 << kTrustedPointerHandleShift;
+
+// When a table has a fixed size (initial_size == maximum_size), compiled
+// call_indirect checks the index against the static kFixedTableSize constant
+// rather than loading the dynamic length of dispatch_table0 (which is 0 on a
+// partially-initialized WasmTrustedInstanceData). Any index in
+// [0, kFixedTableSize) is therefore out-of-bounds for the 0-length
+// empty_dispatch_table on a failed instance.
+const kFixedTableSize = 16;
+const kOutOfBoundsTableIndex = 0;
+
+const builder = new WasmModuleBuilder();
+const sig = builder.addType(kSig_i_v);
+builder.addImportedMemory('m', 'memory', 1, 1);
+const table0 =
+ builder.addTable(wasmRefNullType(sig), kFixedTableSize, kFixedTableSize);
+const table1 = builder.addTable(kWasmFuncRef, 1, 1).exportAs('table');
+builder.addFunction('caller', sig).addBody([
+ kExprI32Const, kOutOfBoundsTableIndex,
+ kExprCallIndirect, sig, table0.index,
+]);
+builder.addActiveElementSegment(table1.index, wasmI32Const(0), [0]);
+const module = builder.toModule();
+
+const wasmMemory = new WebAssembly.Memory({initial: 1, maximum: 1});
+const good = new WebAssembly.Instance(module, {m: {memory: wasmMemory}});
+const goodAddr = Sandbox.getAddressOf(good);
+const instanceTypeId = Sandbox.getInstanceTypeIdOf(good);
+const trustedDataOffset =
+ Sandbox.getFieldOffset(instanceTypeId, 'trusted_data');
+const goodHandle = getField(goodAddr, trustedDataOffset);
+
+// Trigger failed instantiation due to an invalid memory import.
+assertThrows(
+ () => new WebAssembly.Instance(module, {m: {memory: 1}}),
+ WebAssembly.LinkError);
+
+const after = new WebAssembly.Instance(module, {m: {memory: wasmMemory}});
+const afterHandle = getField(Sandbox.getAddressOf(after), trustedDataOffset);
+
+// Attempt to resolve the failed instance's WasmTrustedInstanceData handle
+// (allocated between goodHandle and afterHandle) through the lazy table entry.
+for (let handle = goodHandle + kTrustedPointerHandleStride;
+ handle < afterHandle; handle += kTrustedPointerHandleStride) {
+ setField(goodAddr, trustedDataOffset, handle);
+ good.exports.table.get(0)();
+}
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-562870022.js b/deps/v8/test/mjsunit/sandbox/regress/regress-562870022.js
new file mode 100644
index 00000000000..b636422d097
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-562870022.js
@@ -0,0 +1,15 @@
+// Copyright 2026 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.
+
+// Flags: --sandbox-testing
+
+const rab = new ArrayBuffer(0x1000, { maxByteLength: 0x100000 });
+const sab = new SharedArrayBuffer(0x10000);
+
+const extOffset = Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdOf(rab), 'extension');
+const sabExtHandle = Sandbox.readObjectField(sab, extOffset, 32);
+
+Sandbox.corruptObjectField(rab, extOffset, sabExtHandle, 32);
+rab.resize(0x1000);
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log b/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
index 18f86de1f63..4d3767b5214 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
@@ -1404,9 +1404,9 @@ code-creation,BytecodeHandler,0,18956,0x5574264245c0,36,SetPendingMessage
code-creation,BytecodeHandler,0,18965,0x557426424600,100,Throw
code-creation,BytecodeHandler,0,18974,0x557426424680,100,ReThrow
code-creation,BytecodeHandler,0,18983,0x557426424700,108,Return
-code-creation,BytecodeHandler,0,18991,0x557426424780,188,ThrowReferenceErrorIfHole
-code-creation,BytecodeHandler,0,19001,0x557426424840,120,ThrowSuperNotCalledIfHole
-code-creation,BytecodeHandler,0,19011,0x5574264248c0,120,ThrowSuperAlreadyCalledIfNotHole
+code-creation,BytecodeHandler,0,18991,0x557426424780,188,ThrowReferenceErrorIfTdzHole
+code-creation,BytecodeHandler,0,19001,0x557426424840,120,ThrowSuperNotCalledIfTdzHole
+code-creation,BytecodeHandler,0,19011,0x5574264248c0,120,ThrowSuperAlreadyCalledIfNotTdzHole
code-creation,BytecodeHandler,0,19020,0x557426424940,148,ThrowIfNotSuperConstructor
code-creation,BytecodeHandler,0,19030,0x5574264249e0,128,SwitchOnGeneratorState
code-creation,BytecodeHandler,0,19039,0x557426424a80,580,SuspendGenerator
@@ -1561,7 +1561,7 @@ code-creation,BytecodeHandler,0,20460,0x557426438900,296,ForInPrepare.Wide
code-creation,BytecodeHandler,0,20469,0x557426438a40,64,ForInContinue.Wide
code-creation,BytecodeHandler,0,20478,0x557426438aa0,260,ForInNext.Wide
code-creation,BytecodeHandler,0,20487,0x557426438bc0,36,ForInStep.Wide
-code-creation,BytecodeHandler,0,20496,0x557426438c00,148,ThrowReferenceErrorIfHole.Wide
+code-creation,BytecodeHandler,0,20496,0x557426438c00,148,ThrowReferenceErrorIfTdzHole.Wide
code-creation,BytecodeHandler,0,20506,0x557426438ca0,148,ThrowIfNotSuperConstructor.Wide
code-creation,BytecodeHandler,0,20516,0x557426438d40,128,SwitchOnGeneratorState.Wide
code-creation,BytecodeHandler,0,20525,0x557426438de0,592,SuspendGenerator.Wide
@@ -1713,7 +1713,7 @@ code-creation,BytecodeHandler,0,21956,0x55742644ca40,296,ForInPrepare.ExtraWide
code-creation,BytecodeHandler,0,21965,0x55742644cb80,60,ForInContinue.ExtraWide
code-creation,BytecodeHandler,0,21975,0x55742644cbc0,256,ForInNext.ExtraWide
code-creation,BytecodeHandler,0,21984,0x55742644cce0,36,ForInStep.ExtraWide
-code-creation,BytecodeHandler,0,21994,0x55742644cd20,148,ThrowReferenceErrorIfHole.ExtraWide
+code-creation,BytecodeHandler,0,21994,0x55742644cd20,148,ThrowReferenceErrorIfTdzHole.ExtraWide
code-creation,BytecodeHandler,0,22004,0x55742644cdc0,144,ThrowIfNotSuperConstructor.ExtraWide
code-creation,BytecodeHandler,0,22014,0x55742644ce60,128,SwitchOnGeneratorState.ExtraWide
code-creation,BytecodeHandler,0,22024,0x55742644cf00,588,SuspendGenerator.ExtraWide
diff --git a/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js b/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js
index 68b88692363..810ae387386 100644
--- a/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js
+++ b/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --turbolev --turbofan
+// Flags: --allow-natives-syntax --turbolev --turbofan --multi-mapped-mock-allocator
let big_index = 0x80000000;
let ab = new ArrayBuffer(big_index + 0x40);
diff --git a/deps/v8/test/mjsunit/turbolev/float64-mul-range.js b/deps/v8/test/mjsunit/turbolev/float64-mul-range.js
new file mode 100644
index 00000000000..c216160cdd1
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/float64-mul-range.js
@@ -0,0 +1,20 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev --maglev-range-verification
+
+// Multiplying an unbounded float64 range (which can reach infinity) by zero
+// produces NaN. Range analysis must not assume the result is within [0, 0].
+function test() {
+ let x = 1;
+ for (let i = 0; i < 1024; i++) {
+ x += x;
+ }
+ return x * 0;
+}
+
+%PrepareFunctionForOptimization(test);
+assertTrue(Number.isNaN(test()));
+%OptimizeFunctionOnNextCall(test);
+assertTrue(Number.isNaN(test()));
diff --git a/deps/v8/test/mjsunit/turbolev/instanceof-bound-function-graph-optimizer-map-check.js b/deps/v8/test/mjsunit/turbolev/instanceof-bound-function-graph-optimizer-map-check.js
new file mode 100644
index 00000000000..a49eb9c7f2e
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/instanceof-bound-function-graph-optimizer-map-check.js
@@ -0,0 +1,46 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev
+
+// Reducing `instanceof` on a bound function whose callable isn't a constant
+// leaves a CallBuiltin(OrdinaryHasInstance) behind. The graph optimizer later
+// knows the callable, unwraps the bound target and emits a CheckMaps for it.
+// CheckMaps can eager deopt, so this only works if an eager deopt frame is
+// available, which CallBuiltin (unlike TestInstanceOf) does not have.
+
+function Foo() {}
+function Decoy() {}
+
+// With a null prototype, looking up Symbol.hasInstance on Foo is a "not found"
+// access, which is the path that checks the callable's map.
+Object.setPrototypeOf(Foo, null);
+
+// Decoy shares Foo's map and then transitions away from it, which makes Foo's
+// map unstable. The reduction therefore has to emit an actual CheckMaps rather
+// than just registering a stable map dependency.
+Object.setPrototypeOf(Decoy, null);
+Decoy.x = 1;
+
+const Bound = Function.prototype.bind.call(Foo, null);
+
+function test(obj, n) {
+ let result;
+ // `n` keeps the trip count opaque, so the callable stays a loop phi while the
+ // graph builder runs and it has to fall back to a CallBuiltin. The feedback
+ // stays monomorphic on Bound though, since callers only ever pass n == 1.
+ let c = Bound;
+ for (let i = 0; i < n; i++) {
+ result = obj instanceof c;
+ c = Array;
+ }
+ return result;
+}
+
+%PrepareFunctionForOptimization(test);
+assertFalse(test({}, 1));
+
+%OptimizeFunctionOnNextCall(test);
+assertFalse(test({}, 1));
+assertTrue(test(Object.create(Foo.prototype), 1));
diff --git a/deps/v8/test/mjsunit/turbolev/instanceof-graph-optimizer-map-check.js b/deps/v8/test/mjsunit/turbolev/instanceof-graph-optimizer-map-check.js
new file mode 100644
index 00000000000..98e3f8cf1ea
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/instanceof-graph-optimizer-map-check.js
@@ -0,0 +1,37 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev
+
+// Reducing a TestInstanceOf node in the graph optimizer emits a CheckMaps for
+// the callable, and that check needs an eager deopt frame. TestInstanceOf used
+// to carry lazy deopt info only, so there was no frame to attach to it.
+
+function Ctor1() {}
+function Ctor2() {}
+
+// With a null prototype, looking up Symbol.hasInstance on the callable is a
+// "not found" access, which is the path that checks the callable's map.
+Object.setPrototypeOf(Ctor1, null);
+Object.setPrototypeOf(Ctor2, null);
+
+// Adding a property makes the constructors' map unstable, so the reduction has
+// to emit an actual CheckMaps rather than just depending on a stable map.
+Ctor1.x = 1;
+
+function test(obj) {
+ let result;
+ // The callable is a loop phi rather than a constant, so the graph builder
+ // emits a TestInstanceOf, which the graph optimizer then tries to reduce.
+ for (let i = 0; i < 2; i++) {
+ result = obj instanceof (i ? Ctor1 : Ctor2);
+ }
+ return result;
+}
+
+%PrepareFunctionForOptimization(test);
+assertFalse(test({}));
+%OptimizeFunctionOnNextCall(test);
+assertFalse(test({}));
+assertTrue(test(Object.create(Ctor1.prototype)));
diff --git a/deps/v8/test/mjsunit/turbolev/loop-peel-effect-epochs.js b/deps/v8/test/mjsunit/turbolev/loop-peel-effect-epochs.js
new file mode 100644
index 00000000000..708ef92f78e
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/loop-peel-effect-epochs.js
@@ -0,0 +1,37 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev --turbofan
+
+let shrink = false;
+function callback(array, iteration) {
+ if (shrink && iteration === 1) array.length = 2;
+}
+%NeverOptimizeFunction(callback);
+
+function sum(array, n, callback) {
+ const at = Array.prototype.at;
+ let result = 0;
+ // This loop aligns the effect epochs at the second loop header.
+ for (let i = 0; i < 3; ++i) {
+ callback(null, 9);
+ callback(null, 9);
+ }
+ for (let i = 0; i < n; ++i) {
+ if (i === 0) result += array.length;
+ result += at.call(array, 3);
+ callback(array, i);
+ result += at.call(array, 0);
+ result += array[0];
+ }
+ return result;
+}
+
+const array = [11, 12, 13, 14];
+%PrepareFunctionForOptimization(sum);
+assertEquals(148, sum(array, 4, callback));
+assertEquals(148, sum(array, 4, callback));
+%OptimizeFunctionOnNextCall(sum);
+shrink = true;
+assertTrue(Number.isNaN(sum(array, 4, callback)));
diff --git a/deps/v8/test/mjsunit/turbolev/regress-488090094.js b/deps/v8/test/mjsunit/turbolev/regress-488090094.js
index d61b7a99346..ad1e2540f43 100644
--- a/deps/v8/test/mjsunit/turbolev/regress-488090094.js
+++ b/deps/v8/test/mjsunit/turbolev/regress-488090094.js
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --turbolev
+// Flags: --allow-natives-syntax --turbolev --multi-mapped-mock-allocator
let big_index = 0x80000000;
let ta = new Uint8Array(big_index+0x40);
-ta[big_index] = 42;
function foo(ta, index) {
index |= 0;
@@ -18,6 +17,7 @@ function foo(ta, index) {
assertEquals(0, foo(ta, 10));
assertEquals(0, foo(ta, 0x40000000));
+ta[big_index] = 42;
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(ta, 10));
assertEquals(undefined, foo(ta, -2147483648));
diff --git a/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array-large.js b/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array-large.js
index 87427bae197..9f94372bfe8 100644
--- a/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array-large.js
+++ b/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array-large.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --turbolev --turbofan
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --multi-mapped-mock-allocator
function foo(size) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array.js b/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array.js
index 34bc739fec4..eb418462828 100644
--- a/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array.js
+++ b/deps/v8/test/mjsunit/turbolev/typed-array-length-index-into-typed-array.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --maglev --turbofan
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --multi-mapped-mock-allocator
function foo(size) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/turbolev/typed-array-length-phi.js b/deps/v8/test/mjsunit/turbolev/typed-array-length-phi.js
index b869a7be836..d0ba116719f 100644
--- a/deps/v8/test/mjsunit/turbolev/typed-array-length-phi.js
+++ b/deps/v8/test/mjsunit/turbolev/typed-array-length-phi.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --turbolev --turbofan
-// Flags: --typed-array-length-loading
+// Flags: --typed-array-length-loading --mock-arraybuffer-allocator
function foo(size, b) {
let a = new Uint8Array(size);
diff --git a/deps/v8/test/mjsunit/turbolev/update-jsarray-length.js b/deps/v8/test/mjsunit/turbolev/update-jsarray-length.js
new file mode 100644
index 00000000000..6a0d755974d
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/update-jsarray-length.js
@@ -0,0 +1,56 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turbolev --turbofan
+
+function testInBoundsStoreConstantIndex() {
+ function f(a) {
+ a[0] = 42;
+ return a.length;
+ }
+ %PrepareFunctionForOptimization(f);
+ let a = [1, 2, 3];
+ assertEquals(3, f(a));
+ assertEquals(3, f(a));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(3, f(a));
+ assertEquals(42, a[0]);
+ assertOptimized(f);
+}
+testInBoundsStoreConstantIndex();
+
+function testInBoundsStoreLoop() {
+ function f(a) {
+ for (let i = 0; i < a.length; i++) {
+ a[i] = i * 2;
+ }
+ return a.length;
+ }
+ %PrepareFunctionForOptimization(f);
+ let a = [1, 2, 3, 4, 5];
+ assertEquals(5, f(a));
+ assertEquals(5, f(a));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(5, f(a));
+ assertEquals([0, 2, 4, 6, 8], a);
+ assertOptimized(f);
+}
+testInBoundsStoreLoop();
+
+function testGrowStoreLoop() {
+ function f() {
+ let a = [];
+ for (let i = 0; i < 10; i++) {
+ a[i] = i;
+ }
+ return a.length;
+ }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(10, f());
+ assertEquals(10, f());
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(10, f());
+ assertOptimized(f);
+}
+testGrowStoreLoop();
diff --git a/deps/v8/test/mjsunit/turboshaft/extras-cped.js b/deps/v8/test/mjsunit/turboshaft/extras-cped.js
index d0ee141ae2d..2587765c941 100644
--- a/deps/v8/test/mjsunit/turboshaft/extras-cped.js
+++ b/deps/v8/test/mjsunit/turboshaft/extras-cped.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --turbofan
const {
getExtrasBindingObject,
diff --git a/deps/v8/test/mjsunit/turboshaft/typer-pow-matches-runtime.js b/deps/v8/test/mjsunit/turboshaft/typer-pow-matches-runtime.js
new file mode 100644
index 00000000000..1f0d30678ab
--- /dev/null
+++ b/deps/v8/test/mjsunit/turboshaft/typer-pow-matches-runtime.js
@@ -0,0 +1,57 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax --turboshaft-typed-optimizations
+// Flags: --no-use-std-math-pow
+
+// The Turboshaft typer computes constant sets for `x ** y`. It must use the
+// same pow implementation as the runtime, otherwise typed optimizations can
+// fold comparisons on the result incorrectly.
+//
+// Each base below is an odd 18-bit integer divided by 2, so its cube lies
+// exactly halfway between two doubles. A correctly rounded pow rounds these
+// ties to even (the second column); a pow that is not correctly rounded (such
+// as many system libms) picks either neighbor. If the typer's pow rounds
+// differently than the runtime's, the typer believes `x ** 3` is strictly
+// below or above the rounded value, and one of the two comparisons below gets
+// folded to `true` even though the runtime value is equal.
+
+const kCases = [
+ [104035.5, 1126016297242739.0],
+ [104062.5, 1126893218994140.5],
+ [104161.5, 1130112493874283.5],
+ [104165.5, 1130242694291086.5],
+ [104167.5, 1130307798249422.0],
+ [104169.5, 1130372904707777.5],
+ [104177.5, 1130633355542359.5],
+ [104187.5, 1130958975341797.0],
+ [104191.5, 1131089240764736.0],
+ [104195.5, 1131219516190059.0],
+ [104215.5, 1131871043365874.0],
+ [104221.5, 1132066550289288.5],
+];
+
+function test(body) {
+ const f = new Function('b', body);
+ %PrepareFunctionForOptimization(f);
+ const expected = f(true);
+ f(false);
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(expected, f(true));
+}
+
+for (const [base, rounded] of kCases) {
+ // The other phi input is far below `rounded`, so the comparison can only be
+ // folded if the typer thinks `base ** 3` is below `rounded`.
+ test(`
+ let x = b ? ${base} : 2.5;
+ return x ** 3 < ${rounded};
+ `);
+ // The other phi input is far above `rounded`, so the comparison can only be
+ // folded if the typer thinks `base ** 3` is above `rounded`.
+ test(`
+ let x = b ? ${base} : 1000000.5;
+ return x ** 3 > ${rounded};
+ `);
+}
diff --git a/deps/v8/test/mjsunit/tzoffset-fractional-los-angeles.js b/deps/v8/test/mjsunit/tzoffset-fractional-los-angeles.js
new file mode 100644
index 00000000000..da4e8a3df35
--- /dev/null
+++ b/deps/v8/test/mjsunit/tzoffset-fractional-los-angeles.js
@@ -0,0 +1,62 @@
+// Copyright 2026 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.
+
+// Flags: --icu-timezone-data --allow-natives-syntax
+// Environment Variables: TZ=America/Los_Angeles
+
+// Before time zones were standardized, Los Angeles used local mean time,
+// UTC-07:52:58. getTimezoneOffset() must not truncate that to whole minutes.
+// See https://crbug.com/40814804.
+
+const kLmtOffsetMs = 7 * 3600000 + 52 * 60000 + 58 * 1000; // 28378000
+const kLmtOffsetMin = kLmtOffsetMs / 60000; // 472.9666...
+
+const lmt = new Date(Date.UTC(1675, 0, 1));
+assertEquals(kLmtOffsetMin, lmt.getTimezoneOffset());
+assertFalse(Number.isInteger(lmt.getTimezoneOffset()));
+
+// The point of the bug report: shifting a date by its own offset must make the
+// local fields read back as the original UTC fields. Truncating the offset to
+// 472 minutes lands on 1674-12-31 23:59:02 instead.
+const shifted = new Date(lmt.valueOf() + lmt.getTimezoneOffset() * 60000);
+assertEquals(1675, shifted.getFullYear());
+assertEquals(0, shifted.getMonth());
+assertEquals(1, shifted.getDate());
+assertEquals(0, shifted.getHours());
+assertEquals(0, shifted.getMinutes());
+assertEquals(0, shifted.getSeconds());
+
+// The local time itself already had second precision, so it must agree with
+// the offset.
+assertEquals(16, lmt.getHours());
+assertEquals(7, lmt.getMinutes());
+assertEquals(2, lmt.getSeconds());
+
+// toString() keeps minute precision, per TimeZoneString().
+// https://tc39.es/ecma262/#sec-timezoneestring
+assertTrue(lmt.toString().includes('GMT-0752'), lmt.toString());
+
+// Whole-minute offsets still produce Smis, and PST/PDT are unaffected.
+const pst = new Date(Date.UTC(2020, 0, 1));
+const pdt = new Date(Date.UTC(2020, 6, 1));
+assertEquals(480, pst.getTimezoneOffset());
+assertEquals(420, pdt.getTimezoneOffset());
+assertTrue(%IsSmi(pst.getTimezoneOffset()));
+
+// NaN dates still report NaN.
+assertEquals(NaN, new Date(NaN).getTimezoneOffset());
+
+// Non-Date receivers still throw.
+assertThrows(() => Date.prototype.getTimezoneOffset.call({}), TypeError);
+assertThrows(() => Date.prototype.getTimezoneOffset.call(undefined), TypeError);
+
+// Same results after the builtin is optimized.
+function offsetOf(d) { return d.getTimezoneOffset(); }
+%PrepareFunctionForOptimization(offsetOf);
+assertEquals(kLmtOffsetMin, offsetOf(lmt));
+assertEquals(480, offsetOf(pst));
+%OptimizeFunctionOnNextCall(offsetOf);
+assertEquals(kLmtOffsetMin, offsetOf(lmt));
+assertEquals(480, offsetOf(pst));
+assertEquals(NaN, offsetOf(new Date(NaN)));
diff --git a/deps/v8/test/mjsunit/wasm/exact-types.js b/deps/v8/test/mjsunit/wasm/exact-types.js
index 959dfde2b54..5d622539e84 100644
--- a/deps/v8/test/mjsunit/wasm/exact-types.js
+++ b/deps/v8/test/mjsunit/wasm/exact-types.js
@@ -139,3 +139,70 @@ assertEquals(1, wasm.br_on_cast_fail_exact_s2(s0));
assertEquals(1, wasm.br_on_cast_fail_exact_s2(s1));
assertEquals(0, wasm.br_on_cast_fail_exact_s2(s2));
assertEquals(1, wasm.br_on_cast_fail_exact_s2(null));
+
+(function TestExactArray() {
+ let builder = new WasmModuleBuilder();
+ builder.startRecGroup();
+ let $super = builder.addArray(kWasmI32, {is_mut: false});
+ let $sub = builder.addArray(kWasmI32, {supertype: $super, is_mut: false});
+ builder.endRecGroup();
+
+ builder.addFunction("test_cast", kSig_v_v).exportFunc()
+ .addLocals(wasmRefType($super), 1)
+ .addBody([
+ kExprI32Const, 0,
+ kGCPrefix, kExprArrayNewDefault, $super,
+ kExprLocalSet, 0,
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, kWasmExact, $super,
+ kExprDrop,
+ ]);
+
+ builder.addFunction("test_type_check", kSig_i_v).exportFunc()
+ .addLocals(wasmRefType($super), 1)
+ .addBody([
+ kExprI32Const, 0,
+ kGCPrefix, kExprArrayNewDefault, $super,
+ kExprLocalSet, 0,
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefTest, kWasmExact, $sub,
+ ]);
+
+ let instance = builder.instantiate();
+ instance.exports.test_cast();
+ assertEquals(0, instance.exports.test_type_check());
+})();
+
+(function TestExactRefFunc() {
+ let builder = new WasmModuleBuilder();
+ builder.startRecGroup();
+ let $super = builder.addType(kSig_v_v, kNoSuperType, false);
+ let $sub = builder.addType(kSig_v_v, $super, false);
+ builder.endRecGroup();
+
+ let f = builder.addFunction("f", $super).addBody([]);
+ builder.addDeclarativeElementSegment([f.index]);
+
+ builder.addFunction("test_cast", kSig_v_v).exportFunc()
+ .addLocals(wasmRefType($super), 1)
+ .addBody([
+ kExprRefFunc, f.index,
+ kExprLocalSet, 0,
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, kWasmExact, $super,
+ kExprDrop,
+ ]);
+
+ builder.addFunction("test_type_check", kSig_i_v).exportFunc()
+ .addLocals(wasmRefType($super), 1)
+ .addBody([
+ kExprRefFunc, f.index,
+ kExprLocalSet, 0,
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefTest, kWasmExact, $sub,
+ ]);
+
+ let instance = builder.instantiate();
+ instance.exports.test_cast();
+ assertEquals(0, instance.exports.test_type_check());
+})();
diff --git a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-conflict.js b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-conflict.js
index 89c3d38f7d3..487656e5e80 100644
--- a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-conflict.js
+++ b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-conflict.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --turbo-fast-api-calls --expose-fast-api --no-liftoff --wasm-fast-api
-// Flags: --wasm-lazy-compilation
+// Flags: --wasm-lazy-compilation --turbofan
// Flags: --no-wasm-native-module-cache
// Flags: --fast-api-allow-float-in-sim
diff --git a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-floats.js b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-floats.js
index 8b890770d83..4874d2dcbf6 100644
--- a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-floats.js
+++ b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-floats.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --turbo-fast-api-calls --expose-fast-api --no-liftoff --wasm-fast-api
-// Flags: --wasm-lazy-compilation
+// Flags: --wasm-lazy-compilation --turbofan
// Flags: --fast-api-allow-float-in-sim
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
diff --git a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-i64.js b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-i64.js
index 9d206dca706..7680659db36 100644
--- a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-i64.js
+++ b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-i64.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --turbo-fast-api-calls --expose-fast-api --no-liftoff --wasm-fast-api
-// Flags: --wasm-lazy-compilation
+// Flags: --wasm-lazy-compilation --turbofan
// Flags: --no-wasm-native-module-cache
// Flags: --fast-api-allow-float-in-sim
diff --git a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-tagged.js b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-tagged.js
index 3f0e15216cc..cf2bf8e2568 100644
--- a/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-tagged.js
+++ b/deps/v8/test/mjsunit/wasm/fast-api-calls-with-wellknown-imports-tagged.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --turbo-fast-api-calls --expose-fast-api --no-liftoff --wasm-fast-api
-// Flags: --wasm-lazy-compilation
+// Flags: --wasm-lazy-compilation --turbofan
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
diff --git a/deps/v8/test/mjsunit/wasm/gc-js-interop-private-symbols.js b/deps/v8/test/mjsunit/wasm/gc-js-interop-private-symbols.js
new file mode 100644
index 00000000000..9215406f51c
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/gc-js-interop-private-symbols.js
@@ -0,0 +1,83 @@
+// Copyright 2026 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.
+
+// Flags: --allow-natives-syntax
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Wasm objects are opaque and have a fixed layout; their maps must never
+// transition and no properties may be added to them.
+
+const builder = new WasmModuleBuilder();
+const $struct = builder.addStruct([makeField(kWasmI64, true)]);
+const $array = builder.addArray(kWasmI64);
+
+builder.addFunction('makeStruct', makeSig([], [wasmRefType($struct)]))
+ .exportFunc()
+ .addBody([
+ ...wasmI64Const(0),
+ kGCPrefix, kExprStructNew, $struct,
+ ]);
+
+builder.addFunction('makeArray', makeSig([], [wasmRefType($array)]))
+ .exportFunc()
+ .addBody([
+ ...wasmI64Const(0),
+ ...wasmI32Const(1),
+ kGCPrefix, kExprArrayNew, $array,
+ ]);
+
+builder.addFunction('isStruct', makeSig([kWasmExternRef], [kWasmI32]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefTest, $struct,
+ ]);
+
+builder.addFunction('isArray', makeSig([kWasmExternRef], [kWasmI32]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefTest, $array,
+ ]);
+
+const instance = builder.instantiate();
+const privateSymbol = %CreatePrivateSymbol('private');
+
+// Structs and arrays must retain their type identity after failed assignment.
+const wasmStruct = instance.exports.makeStruct();
+assertEquals(1, instance.exports.isStruct(wasmStruct));
+assertThrows(() => wasmStruct[privateSymbol] = 1, TypeError);
+assertEquals(1, instance.exports.isStruct(wasmStruct));
+
+const wasmArray = instance.exports.makeArray();
+assertEquals(1, instance.exports.isArray(wasmArray));
+assertThrows(() => wasmArray[privateSymbol] = 1, TypeError);
+assertEquals(1, instance.exports.isArray(wasmArray));
+
+// Standard JS private fields (#field) on class return-override must also throw
+// and preserve type identity.
+class Base {
+ constructor(o) {
+ return o;
+ }
+}
+class DerivedWithPrivateField extends Base {
+ #field = 42;
+}
+
+assertThrows(() => new DerivedWithPrivateField(wasmStruct), TypeError);
+assertEquals(1, instance.exports.isStruct(wasmStruct));
+
+assertThrows(() => new DerivedWithPrivateField(wasmArray), TypeError);
+assertEquals(1, instance.exports.isArray(wasmArray));
+
+// Identity hashes used by WeakMap/WeakSet must continue to work.
+const wm = new WeakMap();
+wm.set(wasmStruct, 'struct-value');
+wm.set(wasmArray, 'array-value');
+assertEquals('struct-value', wm.get(wasmStruct));
+assertEquals('array-value', wm.get(wasmArray));
diff --git a/deps/v8/test/mjsunit/wasm/indirect-tables.js b/deps/v8/test/mjsunit/wasm/indirect-tables.js
index b4a94566b27..c0e84790b2a 100644
--- a/deps/v8/test/mjsunit/wasm/indirect-tables.js
+++ b/deps/v8/test/mjsunit/wasm/indirect-tables.js
@@ -603,10 +603,10 @@ function js_div(a, b) { return (a / b) | 0; }
var mem_1 = new WebAssembly.Memory({initial: 1});
var mem_2 = new WebAssembly.Memory({initial: 1});
- var view_1 = new Int32Array(mem_1.buffer);
- var view_2 = new Int32Array(mem_2.buffer);
- view_1[0] = 1;
- view_2[0] = 1000;
+ var view_1 = new DataView(mem_1.buffer);
+ var view_2 = new DataView(mem_2.buffer);
+ view_1.setInt32(0, 1, true);
+ view_2.setInt32(0, 1000, true);
let builder = new WasmModuleBuilder();
let sig = builder.addType(kSig_i_v);
@@ -674,8 +674,8 @@ function js_div(a, b) { return (a / b) | 0; }
]).exportAs('main');
let mem = new WebAssembly.Memory({initial:1});
- let view = new Int32Array(mem.buffer);
- view[0] = 4;
+ let view = new DataView(mem.buffer);
+ view.setInt32(0, 4, true);
let module2 = new WebAssembly.Module(builder.toBuffer());
let instance2 = new WebAssembly.Instance(module2, {
@@ -851,8 +851,8 @@ function js_div(a, b) { return (a / b) | 0; }
})();
function setMemI32(instance, offset, val) {
- var array = new Int32Array(instance.exports.memory.buffer);
- array[offset/4] = val;
+ var view = new DataView(instance.exports.memory.buffer);
+ view.setInt32(offset, val, true);
}
function makeFun(val) {
diff --git a/deps/v8/test/mjsunit/wasm/recognize-imports.js b/deps/v8/test/mjsunit/wasm/recognize-imports.js
index 994ccf6717d..6b20356c8e5 100644
--- a/deps/v8/test/mjsunit/wasm/recognize-imports.js
+++ b/deps/v8/test/mjsunit/wasm/recognize-imports.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --allow-natives-syntax --wasm-stringref
+// Flags: --allow-natives-syntax --wasm-stringref --wasm-tier-up
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
diff --git a/deps/v8/test/mjsunit/wasm/redundant-shuffle-lanes.js b/deps/v8/test/mjsunit/wasm/redundant-shuffle-lanes.js
index 94f0f97dfcd..de81bcd6366 100644
--- a/deps/v8/test/mjsunit/wasm/redundant-shuffle-lanes.js
+++ b/deps/v8/test/mjsunit/wasm/redundant-shuffle-lanes.js
@@ -2,9 +2,216 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Flags: --future-wasm-simd-opt
+
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
d8.file.execute('test/mjsunit/value-helper.js');
+function RunBinaryPassThruShuffleTest(config) {
+ print(config.name);
+ const builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1);
+ builder.exportMemoryAs("memory");
+ const shuffle = [
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ ];
+ const simd = [
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kSimdPrefix, kExprI8x16Shuffle,
+ ...shuffle,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kSimdPrefix, kExprI8x16Shuffle,
+ ...shuffle,
+ ...SimdInstr(config.op),
+ kSimdPrefix, kExprI8x16ExtractLaneS, 0,
+ ];
+ builder.addFunction("simd", config.sig).addBody(simd).exportFunc();
+ builder.addFunction("scalar", config.sig).addBody(config.scalar).exportFunc();
+ const wasm = builder.instantiate().exports;
+ const memory = new Uint8Array(wasm.memory.buffer);
+ for (let i = 0; i < 64; ++i) {
+ memory[i] = int8_array[i % int8_array.length];
+ }
+ const inputs = [[0, 0], [4, 8], [10, 14]];
+ for (const [left, right] of inputs) {
+ assertEquals(wasm.scalar(left, right), wasm.simd(left, right));
+ }
+}
+
+(function BinaryPassThruShuffleLanes() {
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleI8x16Add",
+ sig: kSig_i_ii,
+ op: kExprI8x16Add,
+ scalar: [
+ kExprLocalGet, 0,
+ kExprI32LoadMem8S, 0, 0,
+ kExprLocalGet, 1,
+ kExprI32LoadMem8S, 0, 0,
+ kExprI32Add,
+ ...wasmI32Const(24),
+ kExprI32Shl,
+ ...wasmI32Const(24),
+ kExprI32ShrS,
+ ],
+ });
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleI16x8Eq",
+ sig: kSig_i_ii,
+ op: kExprI16x8Eq,
+ scalar: [
+ ...wasmI32Const(0),
+ kExprLocalGet, 0,
+ kExprI32LoadMem16U, 0, 0,
+ kExprLocalGet, 1,
+ kExprI32LoadMem16U, 0, 0,
+ kExprI32Eq,
+ kExprI32Sub,
+ ],
+ });
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleI32x4Eq",
+ sig: kSig_i_ii,
+ op: kExprI32x4Eq,
+ scalar: [
+ ...wasmI32Const(0),
+ kExprLocalGet, 0,
+ kExprI32LoadMem, 0, 0,
+ kExprLocalGet, 1,
+ kExprI32LoadMem, 0, 0,
+ kExprI32Eq,
+ kExprI32Sub,
+ ],
+ });
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleI64x2Eq",
+ sig: kSig_i_ii,
+ op: kExprI64x2Eq,
+ scalar: [
+ ...wasmI32Const(0),
+ kExprLocalGet, 0,
+ kExprI64LoadMem, 0, 0,
+ kExprLocalGet, 1,
+ kExprI64LoadMem, 0, 0,
+ kExprI64Eq,
+ kExprI32Sub,
+ ],
+ });
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleF32x4Eq",
+ sig: kSig_i_ii,
+ op: kExprF32x4Eq,
+ scalar: [
+ ...wasmI32Const(0),
+ kExprLocalGet, 0,
+ kExprF32LoadMem, 0, 0,
+ kExprLocalGet, 1,
+ kExprF32LoadMem, 0, 0,
+ kExprF32Eq,
+ kExprI32Sub,
+ ],
+ });
+ RunBinaryPassThruShuffleTest({
+ name: "BinaryPassThruShuffleF64x2Eq",
+ sig: kSig_i_ii,
+ op: kExprF64x2Eq,
+ scalar: [
+ ...wasmI32Const(0),
+ kExprLocalGet, 0,
+ kExprF64LoadMem, 0, 0,
+ kExprLocalGet, 1,
+ kExprF64LoadMem, 0, 0,
+ kExprF64Eq,
+ kExprI32Sub,
+ ],
+ });
+})();
+
+function RunNarrowConvertShuffleTest(config) {
+ print(config.name);
+ const builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1);
+ builder.exportMemoryAs("memory");
+ const simd = [
+ // The second lane of this shuffle supplies the second lane of the result.
+ // Narrowing conversions change lane width, so they are not lane-wise
+ // operations.
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kSimdPrefix, kExprI8x16Shuffle,
+ ...config.shuffle,
+ // The second input supplies the high half of the result.
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ ...SimdInstr(config.op),
+ kSimdPrefix, config.extract, config.lane,
+ ];
+ builder.addFunction("simd", kSig_i_ii).addBody(simd).exportFunc();
+ const wasm = builder.instantiate().exports;
+ const memory = new DataView(wasm.memory.buffer);
+ for (let i = 0; i < config.input_lanes.length; ++i) {
+ config.store.call(memory, 16 + i * config.input_size,
+ config.input_lanes[i], true);
+ }
+ assertEquals(config.expected, wasm.simd(0, 16));
+}
+
+(function NarrowConvertIsNotLaneWise() {
+ const i16_shuffle = [
+ 0x00, 0x01, 0x0e, 0x0f, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x03,
+ ];
+ const i32_shuffle = [
+ 0x00, 0x01, 0x02, 0x03, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x08, 0x09, 0x0a, 0x0b, 0x04, 0x05, 0x06, 0x07,
+ ];
+ for (const [name, op, extract] of [
+ ["I8x16SConvertI16x8", kExprI8x16SConvertI16x8,
+ kExprI8x16ExtractLaneS],
+ ["I8x16UConvertI16x8", kExprI8x16UConvertI16x8,
+ kExprI8x16ExtractLaneU],
+ ]) {
+ RunNarrowConvertShuffleTest({
+ name,
+ op,
+ extract,
+ lane: 1,
+ shuffle: i16_shuffle,
+ input_size: 2,
+ input_lanes: [11, 22, 33, 44, 55, 66, 77, 88],
+ store: DataView.prototype.setInt16,
+ expected: 88,
+ });
+ }
+ for (const [name, op, extract] of [
+ ["I16x8SConvertI32x4", kExprI16x8SConvertI32x4,
+ kExprI16x8ExtractLaneS],
+ ["I16x8UConvertI32x4", kExprI16x8UConvertI32x4,
+ kExprI16x8ExtractLaneU],
+ ]) {
+ RunNarrowConvertShuffleTest({
+ name,
+ op,
+ extract,
+ lane: 1,
+ shuffle: i32_shuffle,
+ input_size: 4,
+ input_lanes: [1111, 2222, 3333, 4444],
+ store: DataView.prototype.setInt32,
+ expected: 4444,
+ });
+ }
+})();
+
(function LowLeftHighHighRightLow() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
diff --git a/deps/v8/test/mjsunit/wasm/regress-561849345.js b/deps/v8/test/mjsunit/wasm/regress-561849345.js
new file mode 100644
index 00000000000..2e3436d5575
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/regress-561849345.js
@@ -0,0 +1,100 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-wrapper-tiering-budget=1
+
+// When a Wasm instance created in one realm (importer realm) calls an imported
+// sloppy-mode JS function defined in another realm (callee realm), the `this`
+// receiver must be bound to the callee's global proxy
+// (`callee_context->native_context()->global_proxy()`), not the importing
+// Wasm instance's `WasmImportData::native_context` global proxy, both before
+// and after Turboshaft Wasm-to-JS wrapper tier-up.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+const imp = builder.addImport('m', 'fn', kSig_r_v);
+builder.addFunction('call_import', kSig_r_v)
+ .addBody([kExprCallFunction, imp])
+ .exportFunc();
+const module = builder.toModule();
+
+function instantiateInForeignRealm(jsFunc) {
+ const foreignRealm = Realm.createAllowCrossRealmAccess();
+ const foreignGlobal = Realm.global(foreignRealm);
+ const foreignInstance =
+ new foreignGlobal.WebAssembly.Instance(module, {m: {fn: jsFunc}});
+ return {instance: foreignInstance, foreignGlobal};
+}
+
+// Test 1: Top-level sloppy JS function from main realm imported into a Wasm
+// instance instantiated via a cross-realm WebAssembly.Instance constructor.
+// Verify `this === globalThis` and `this !== foreignGlobal` across multiple calls
+// (spanning generic wrapper and tiered-up Turboshaft wrapper).
+(function testTopLevelSloppyFunction() {
+ function sloppyTarget() {
+ return this;
+ }
+
+ const {instance, foreignGlobal} = instantiateInForeignRealm(sloppyTarget);
+ for (let i = 0; i < 5; ++i) {
+ const receiver = instance.exports.call_import();
+ assertSame(globalThis, receiver);
+ assertNotSame(foreignGlobal, receiver);
+ }
+})();
+
+// Test 2: Sloppy closure JS function (capturing a local variable so
+// JSFunction::context is a FunctionContext rather than directly a NativeContext)
+// imported into the foreign realm's Wasm instance. Verify `this === globalThis`
+// and that captured variable access remains intact across tier-up.
+(function testSloppyClosure() {
+ let counter = 0;
+ function sloppyClosure() {
+ counter++;
+ return this;
+ }
+
+ const {instance, foreignGlobal} = instantiateInForeignRealm(sloppyClosure);
+ for (let i = 0; i < 5; ++i) {
+ const receiver = instance.exports.call_import();
+ assertSame(globalThis, receiver);
+ assertNotSame(foreignGlobal, receiver);
+ assertEquals(i + 1, counter);
+ }
+})();
+
+// Test 3: Strict JS function imported across realms (`this === undefined`
+// across tier-up).
+(function testStrictFunction() {
+ function strictTarget() {
+ 'use strict';
+ return this;
+ }
+
+ const {instance, foreignGlobal} = instantiateInForeignRealm(strictTarget);
+ for (let i = 0; i < 5; ++i) {
+ const receiver = instance.exports.call_import();
+ assertSame(undefined, receiver);
+ }
+})();
+
+// Test 4: Reverse realm direction with arity mismatch.
+// Wasm instance in the main realm importing a sloppy JS function with parameters
+// (a, b) defined in foreignRealm. Verify `this === foreignGlobal` and
+// `this !== globalThis` across tier-up.
+(function testReverseRealmWithArityMismatch() {
+ const foreignRealm = Realm.createAllowCrossRealmAccess();
+ const foreignGlobal = Realm.global(foreignRealm);
+ const foreignSloppy = Realm.eval(
+ foreignRealm,
+ "(function foreignSloppy(a, b) { return this; })");
+
+ const instance = new WebAssembly.Instance(module, {m: {fn: foreignSloppy}});
+ for (let i = 0; i < 5; ++i) {
+ const receiver = instance.exports.call_import();
+ assertSame(foreignGlobal, receiver);
+ assertNotSame(globalThis, receiver);
+ }
+})();
diff --git a/deps/v8/test/mjsunit/wasm/regress-564326756.js b/deps/v8/test/mjsunit/wasm/regress-564326756.js
new file mode 100644
index 00000000000..e3cc56c3699
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/regress-564326756.js
@@ -0,0 +1,136 @@
+// Copyright 2026 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.
+
+// Flags: --wasm-wrapper-tiering-budget=250
+
+// WasmWrapperCache::ModificationScope::AddWrapper updated the shared
+// WasmCodePointerTable entry before flushing the instruction cache. On ARM64
+// CPUs with non-coherent instruction/data caches (e.g. Apple Silicon), a worker
+// thread concurrently calling an import of the same signature could jump to the
+// newly published wrapper address and fetch stale L1I cache lines (SIGILL).
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+(function TestConcurrentWasmToJSWrapperTierUp() {
+ const kNumSigs = 64;
+ const kImportsPerSig = 16;
+ const kNumReaders = 3;
+ // Lowering `--wasm-wrapper-tiering-budget` from its default (1000) to 250
+ // makes the compiler thread trigger tier-up 4x faster, while 16 imports *
+ // 249 calls = 3984 reader calls (~60us on Apple Silicon) spans the
+ // CompileWrapper window without any single reader import's budget reaching 0.
+ const kBudget = 250;
+
+ // 1. Build a Wasm module with 64 distinct 7-parameter signatures (`s = 0..63`)
+ // and 16 imports (`f_<s>_0..15`) per signature:
+ // - `compile_<s>(count)`: calls `f_<s>_0` `count` times to trigger tier-up.
+ // - `read_<s>(max_iters)`: calls `f_<s>_0..15` while `--max_iters > 0` and
+ // `Atomics.load(mem, 4) <= s + 1` (so readers keep calling through `s`
+ // after `AddWrapper(s)` finishes on native hardware, but bail out early on
+ // slow simulator builds once the compiler thread moves past `s + 1`).
+ const builder = new WasmModuleBuilder();
+ builder.addImportedMemory('m', 'mem', 1, 1, true);
+ const makeParams = (s) => [0, 1, 2, 3, 4, 5, 6].map(
+ b => (s & (1 << b)) ? kWasmExternRef : kWasmI32);
+
+ for (let s = 0; s < kNumSigs; s++) {
+ const sig = builder.addType(makeSig(makeParams(s), [kWasmI32]));
+ for (let j = 0; j < kImportsPerSig; j++) {
+ builder.addImport('m', `f_${s}_${j}`, sig);
+ }
+ }
+
+ for (let s = 0; s < kNumSigs; s++) {
+ const args = makeParams(s).flatMap(
+ t => t === kWasmExternRef ? [kExprRefNull, kExternRefCode]
+ : [kExprI32Const, 0]);
+ const callOne = (j) => [
+ ...args,
+ kExprCallFunction, ...wasmUnsignedLeb(s * kImportsPerSig + j),
+ kExprDrop,
+ ];
+ const callAll = [];
+ for (let j = 0; j < kImportsPerSig; j++) callAll.push(...callOne(j));
+
+ builder.addFunction(`compile_${s}`, kSig_v_i)
+ .addBody([
+ kExprLoop, kWasmVoid,
+ ...callOne(0),
+ kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, kExprLocalTee, 0,
+ kExprBrIf, 0,
+ kExprEnd,
+ ])
+ .exportFunc();
+
+ builder.addFunction(`read_${s}`, kSig_v_i)
+ .addBody([
+ kExprLoop, kWasmVoid,
+ ...callAll,
+ kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, kExprLocalTee, 0,
+ kExprI32Const, 0, kExprI32GtS,
+ kExprI32Const, 4, kAtomicPrefix, kExprI32AtomicLoad, 2, 0,
+ kExprI32Const, ...wasmSignedLeb(s + 1), kExprI32LeS,
+ kExprI32And,
+ kExprBrIf, 0,
+ kExprEnd,
+ ])
+ .exportFunc();
+ }
+
+ // 2. Shared synchronization state inside the imported WebAssembly.Memory:
+ // - `sync[0]` (byte offset 0): count of workers that finished instantiation.
+ // - `sync[1]` (byte offset 4): current signature `s` being compiled.
+ const module = builder.toModule();
+ const memory = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});
+ const sync = new Int32Array(memory.buffer);
+ Atomics.store(sync, 1, -1);
+
+ // 3. Reader workers: instantiate the module, signal readiness (`sync[0]`),
+ // and spin-wait for each `s` before calling `read_<s>(kBudget - 1)`.
+ function workerCode() {
+ onmessage = function({data: {module, memory, kNumSigs, kImportsPerSig, kBudget}}) {
+ const sync = new Int32Array(memory.buffer);
+ const m = {mem: memory};
+ for (let s = 0; s < kNumSigs; s++) {
+ for (let j = 0; j < kImportsPerSig; j++) m[`f_${s}_${j}`] = () => 1;
+ }
+ const {exports} = new WebAssembly.Instance(module, {m});
+
+ Atomics.add(sync, 0, 1);
+ for (let s = 0; s < kNumSigs; s++) {
+ while (Atomics.load(sync, 1) < s) {}
+ exports[`read_${s}`](kBudget - 1);
+ }
+ postMessage('ok');
+ };
+ }
+
+ const workers = [];
+ for (let w = 0; w < kNumReaders; w++) {
+ const worker = new Worker(workerCode, {type: 'function'});
+ worker.postMessage({module, memory, kNumSigs, kImportsPerSig, kBudget});
+ workers.push(worker);
+ }
+
+ // 4. Main thread (compiler): wait for all workers to instantiate, then step
+ // through `s = 0..47`, releasing readers on `s` and calling `compile_<s>`.
+ const m = {mem: memory};
+ for (let s = 0; s < kNumSigs; s++) {
+ for (let j = 0; j < kImportsPerSig; j++) m[`f_${s}_${j}`] = () => 1;
+ }
+ const {exports} = new WebAssembly.Instance(module, {m});
+
+ while (Atomics.load(sync, 0) < workers.length) {}
+
+ for (let s = 0; s < kNumSigs; s++) {
+ Atomics.store(sync, 1, s);
+ exports[`compile_${s}`](kBudget);
+ }
+ Atomics.store(sync, 1, kNumSigs + 1);
+
+ for (const w of workers) {
+ assertEquals('ok', w.getMessage());
+ w.terminate();
+ }
+})();
diff --git a/deps/v8/test/mjsunit/wasm/shared-everything/post-message.js b/deps/v8/test/mjsunit/wasm/shared-everything/post-message.js
index 2c46a3332f4..0abac6aee8b 100644
--- a/deps/v8/test/mjsunit/wasm/shared-everything/post-message.js
+++ b/deps/v8/test/mjsunit/wasm/shared-everything/post-message.js
@@ -26,7 +26,9 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let worker = new Worker(function() {
onmessage = function({data:msg}) {
- d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+ if (typeof WasmModuleBuilder !== 'function') {
+ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+ }
let builder = new WasmModuleBuilder();
@@ -48,13 +50,16 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let value0 = 5;
let value1 = 10;
let struct_obj_pre = instance.exports.producer(value0);
- assertEquals(instance.exports.getter(struct_obj_pre), value0);
- worker.postMessage({struct: struct_obj_pre});
+ assertEquals(value0, instance.exports.getter(struct_obj_pre));
+ // Make sure we can roundtrip the same object twice.
+ for (let i = 0; i < 2; i++) {
+ worker.postMessage({struct: struct_obj_pre});
- let struct_obj_post = worker.getMessage().struct;
+ let struct_obj_post = worker.getMessage().struct;
- assertEquals(struct_obj_pre, struct_obj_post);
- assertEquals(instance.exports.getter(struct_obj_post), value1);
+ assertEquals(struct_obj_pre, struct_obj_post);
+ assertEquals(value1, instance.exports.getter(struct_obj_post));
+ }
})();
// Trying to postMessage a non-shared struct should fail.
@@ -96,7 +101,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let value0 = 5;
let struct_obj_pre = instance.exports.producer(value0);
- assertEquals(instance.exports.getter(struct_obj_pre), value0);
+ assertEquals(value0, instance.exports.getter(struct_obj_pre));
assertThrows(() => worker.postMessage({struct: struct_obj_pre}), Error,
"[object Object] could not be cloned.");
})();
@@ -141,13 +146,13 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let value0 = 5;
let value1 = 10;
let array_obj_pre = instance.exports.producer(value0);
- assertEquals(instance.exports.getter(array_obj_pre), value0);
+ assertEquals(value0, instance.exports.getter(array_obj_pre));
worker.postMessage({array: array_obj_pre});
let array_obj_post = worker.getMessage().array;
assertEquals(array_obj_pre, array_obj_post);
- assertEquals(instance.exports.getter(array_obj_post), value1);
+ assertEquals(value1, instance.exports.getter(array_obj_post));
})();
// Trying to postMessage a non-shared array should fail.
@@ -191,7 +196,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let value0 = 5;
let value1 = 10;
let array_obj_pre = instance.exports.producer(value0);
- assertEquals(instance.exports.getter(array_obj_pre), value0);
+ assertEquals(value0, instance.exports.getter(array_obj_pre));
assertThrows(() => worker.postMessage({array: array_obj_pre}), Error,
"[object Object] could not be cloned.");
})();
@@ -238,5 +243,5 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let struct_obj = worker.getMessage().struct;
- assertEquals(instance.exports.getter(struct_obj), value);
+ assertEquals(value, instance.exports.getter(struct_obj));
})();
diff --git a/deps/v8/test/mjsunit/wasm/shared-everything/wait-queue.js b/deps/v8/test/mjsunit/wasm/shared-everything/wait-queue.js
index 4335bd9de52..3656f4969b1 100644
--- a/deps/v8/test/mjsunit/wasm/shared-everything/wait-queue.js
+++ b/deps/v8/test/mjsunit/wasm/shared-everything/wait-queue.js
@@ -97,16 +97,19 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
wasm.cast_null_to_null();
})();
-(function TestWaitNotify() {
- print(arguments.callee.name);
+function typeToName(type) {
+ if (type == kWasmI32) return "i32";
+ else if (type == kWasmI64) return "i64";
+ else return "eqref";
+}
- let value0 = 42;
- let value1 = 10;
+function TestWaitNotifyStruct(type, const_op, value0, value1) {
+ print(`${arguments.callee.name} ${typeToName(type)}`);
let builder = new WasmModuleBuilder();
let struct = builder.addStruct(
- {fields: [makeField(kWasmI32, true),
+ {fields: [makeField(type, true),
makeField(wasmRefNullType(kWasmWaitqueueRef).shared(), true)],
shared: true});
@@ -114,12 +117,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let global = builder.addGlobal(
struct_type, true, false,
- [kExprI32Const, value0, kAtomicPrefix, kExprWaitqueueNew,
+ [...const_op(value0), kAtomicPrefix, kExprWaitqueueNew,
kGCPrefix, kExprStructNew, struct]);
builder.addExportOfKind("global", kExternalGlobal, global.index);
- builder.addFunction("make", makeSig([kWasmI32], [struct_type]))
+ builder.addFunction("make", makeSig([type], [struct_type]))
.addBody([kExprLocalGet, 0, kAtomicPrefix, kExprWaitqueueNew,
kGCPrefix, kExprStructNew, struct])
.exportFunc();
@@ -137,7 +140,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
.exportFunc();
builder.addFunction(
- "wait", makeSig([struct_type, kWasmI32, kWasmI64], [kWasmI32]))
+ "wait", makeSig([struct_type, type, kWasmI64], [kWasmI32]))
.addBody([kExprLocalGet, 0,
kExprLocalGet, 0, kGCPrefix, kExprStructGet, struct, 1,
kExprLocalGet, 1, kExprLocalGet, 2,
@@ -145,7 +148,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
.exportFunc();
builder.addFunction(
- "wait_null_struct", makeSig([kWasmI32, kWasmI64], [kWasmI32]))
+ "wait_null_struct", makeSig([type, kWasmI64], [kWasmI32]))
.addBody([kExprRefNull, struct, kAtomicPrefix, kExprWaitqueueNew,
kExprLocalGet, 0, kExprLocalGet, 1,
kAtomicPrefix, kExprStructWait, struct, 0])
@@ -153,7 +156,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
builder.addFunction(
"wait_null_waitqueue",
- makeSig([struct_type, kWasmI32, kWasmI64], [kWasmI32]))
+ makeSig([struct_type, type, kWasmI64], [kWasmI32]))
.addBody([kExprLocalGet, 0,
kExprRefNull, kWasmSharedTypeForm, kWaitqueueRefCode,
kExprLocalGet, 1, kExprLocalGet, 2,
@@ -286,4 +289,162 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
worker.terminate();
worker2.terminate();
-})();
+}
+
+TestWaitNotifyStruct(kWasmI32, wasmI32Const, 42, 10);
+TestWaitNotifyStruct(kWasmI64, wasmI64Const, (1n << 40n) + 42n,
+ (1n << 40n) + 10n);
+TestWaitNotifyStruct(
+ wasmRefNullType(kWasmEqRef).shared(),
+ v => [...wasmI32Const(v), kGCPrefix, kExprRefI31Shared], 42, 10);
+
+function TestWaitNotifyArray(type, const_op, value0, value1) {
+ print(`${arguments.callee.name} ${typeToName(type)}`);
+
+ let builder = new WasmModuleBuilder();
+
+ let array = builder.addArray(type, {shared: true});
+ let array_type = wasmRefNullType(array);
+
+ let struct = builder.addStruct(
+ {fields: [makeField(array_type, true),
+ makeField(wasmRefNullType(kWasmWaitqueueRef).shared(), true)],
+ shared: true});
+
+ let struct_type = wasmRefNullType(struct);
+
+ let global = builder.addGlobal(
+ struct_type, true, false,
+ [...const_op(value1), ...const_op(value0),
+ kGCPrefix, kExprArrayNewFixed, array, 2,
+ kAtomicPrefix, kExprWaitqueueNew,
+ kGCPrefix, kExprStructNew, struct]);
+
+ builder.addExportOfKind("global", kExternalGlobal, global.index);
+
+ builder.addFunction("make", makeSig([type], [struct_type]))
+ .addBody([...const_op(value1), kExprLocalGet, 0,
+ kGCPrefix, kExprArrayNewFixed, array, 2,
+ kAtomicPrefix, kExprWaitqueueNew,
+ kGCPrefix, kExprStructNew, struct])
+ .exportFunc();
+
+ builder.addFunction(
+ "notify", makeSig([struct_type, kWasmI32], [kWasmI32]))
+ .addBody([kExprLocalGet, 0, kGCPrefix, kExprStructGet, struct, 1,
+ kExprLocalGet, 1,
+ kAtomicPrefix, kExprWaitqueueNotify])
+ .exportFunc();
+
+ builder.addFunction(
+ "wait", makeSig([struct_type, kWasmI32, type, kWasmI64], [kWasmI32]))
+ .addBody([kExprLocalGet, 0, kGCPrefix, kExprStructGet, struct, 0,
+ kExprLocalGet, 0, kGCPrefix, kExprStructGet, struct, 1,
+ kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 3,
+ kAtomicPrefix, kExprArrayWait, array])
+ .exportFunc();
+
+ builder.addFunction(
+ "wait_null_array", makeSig([kWasmI32, type, kWasmI64], [kWasmI32]))
+ .addBody([kExprRefNull, array, kAtomicPrefix, kExprWaitqueueNew,
+ kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
+ kAtomicPrefix, kExprArrayWait, array])
+ .exportFunc();
+
+ builder.addFunction(
+ "wait_null_waitqueue",
+ makeSig([struct_type, kWasmI32, type, kWasmI64], [kWasmI32]))
+ .addBody([kExprLocalGet, 0, kGCPrefix, kExprStructGet, struct, 0,
+ kExprRefNull, kWasmSharedTypeForm, kWaitqueueRefCode,
+ kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 3,
+ kAtomicPrefix, kExprArrayWait, array])
+ .exportFunc();
+
+ let module = builder.toModule();
+
+ let instance = new WebAssembly.Instance(module, {});
+
+ let struct_from_function = instance.exports.make(value0);
+ let struct_global = instance.exports.global.value;
+
+ function workerCode() {
+ instance = undefined;
+ onmessage = function({data:msg}) {
+ if (!instance) {
+ instance = new WebAssembly.Instance(msg.module, {});
+ postMessage('instantiated');
+ } else {
+ try {
+ let result = msg.kind == "normal" ?
+ instance.exports.wait(...msg.arguments)
+ : msg.kind == "null_array" ?
+ instance.exports.wait_null_array(...msg.arguments)
+ : instance.exports.wait_null_waitqueue(...msg.arguments);
+ print(`[worker] ${result}`);
+ postMessage(result);
+ } catch (e) {
+ if (e instanceof WebAssembly.RuntimeError &&
+ e.message.includes("dereferencing a null pointer")) {
+ postMessage("dereferencing a null pointer");
+ } else if (e instanceof WebAssembly.RuntimeError &&
+ e.message.includes("array element access out of bounds")) {
+ postMessage("array element access out of bounds");
+ } else {
+ postMessage("unknown exception");
+ }
+ }
+ }
+ return;
+ }
+ }
+
+ let worker = new Worker(workerCode, {type: 'function'});
+
+ worker.postMessage({module: module});
+ assertEquals('instantiated', worker.getMessage());
+
+ const k1ms = 1_000_000n;
+ const k10s = 10_000_000_000n;
+
+ worker.postMessage({kind: "null_array", arguments: [1, value1, k1ms]});
+ assertEquals("dereferencing a null pointer", worker.getMessage());
+ worker.postMessage({kind: "null_waitqueue",
+ arguments: [struct_from_function, 1, value1, k1ms]});
+ assertEquals("dereferencing a null pointer", worker.getMessage());
+ worker.postMessage({kind: "normal",
+ arguments: [struct_from_function, 2, value1, k1ms]});
+ assertEquals("array element access out of bounds", worker.getMessage());
+
+ for (struct_obj of [struct_from_function, struct_global]) {
+ worker.postMessage({kind: "normal",
+ arguments: [struct_obj, 1, value1, k1ms]});
+ assertEquals(kAtomicWaitNotEqual, worker.getMessage());
+
+ worker.postMessage({kind: "normal",
+ arguments: [struct_obj, 1, value0, k1ms]});
+ assertEquals(kAtomicWaitTimedOut, worker.getMessage());
+
+ worker.postMessage({kind: "normal",
+ arguments: [struct_obj, 1, value0, k10s]});
+ const started = performance.now();
+ let notified;
+
+ while ((notified = instance.exports.notify(struct_obj, 1)) === 0) {
+ const now = performance.now();
+ if (now - started > k10s) {
+ throw new Error('Could not notify worker within 10s');
+ }
+ }
+ assertEquals(1, notified);
+ assertEquals(kAtomicWaitOk, worker.getMessage());
+ }
+
+ worker.terminate();
+}
+
+TestWaitNotifyArray(kWasmI32, wasmI32Const, 42, 10);
+TestWaitNotifyArray(
+ kWasmI64, wasmI64Const, (1n << 40n) + 42n, (1n << 40n) + 10n);
+TestWaitNotifyArray(
+ wasmRefNullType(kWasmEqRef).shared(),
+ v => [...wasmI32Const(v), kGCPrefix, kExprRefI31Shared], 42, 10);
diff --git a/deps/v8/test/mjsunit/wasm/simd-int-narrowing.js b/deps/v8/test/mjsunit/wasm/simd-int-narrowing.js
new file mode 100644
index 00000000000..9bd985080e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/simd-int-narrowing.js
@@ -0,0 +1,91 @@
+// Copyright 2026 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.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/value-helper.js');
+
+// Test signed and unsigned SIMD narrowing.
+const builder = new WasmModuleBuilder();
+
+builder.addFunction('i8x16_narrow_s', kSig_ii_ii)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI16x8Splat),
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI16x8Splat),
+ ...SimdInstr(kExprI8x16SConvertI16x8),
+ kExprLocalTee, 2,
+ ...SimdInstr(kExprI8x16ExtractLaneS), 0,
+ kExprLocalGet, 2,
+ ...SimdInstr(kExprI8x16ExtractLaneS), 8,
+ ])
+ .exportFunc();
+
+builder.addFunction('i8x16_narrow_u', kSig_ii_ii)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI16x8Splat),
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI16x8Splat),
+ ...SimdInstr(kExprI8x16UConvertI16x8),
+ kExprLocalTee, 2,
+ ...SimdInstr(kExprI8x16ExtractLaneU), 0,
+ kExprLocalGet, 2,
+ ...SimdInstr(kExprI8x16ExtractLaneU), 8,
+ ])
+ .exportFunc();
+
+builder.addFunction('i16x8_narrow_s', kSig_ii_ii)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI32x4Splat),
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI32x4Splat),
+ ...SimdInstr(kExprI16x8SConvertI32x4),
+ kExprLocalTee, 2,
+ ...SimdInstr(kExprI16x8ExtractLaneS), 0,
+ kExprLocalGet, 2,
+ ...SimdInstr(kExprI16x8ExtractLaneS), 4,
+ ])
+ .exportFunc();
+
+builder.addFunction('i16x8_narrow_u', kSig_ii_ii)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI32x4Splat),
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI32x4Splat),
+ ...SimdInstr(kExprI16x8UConvertI32x4),
+ kExprLocalTee, 2,
+ ...SimdInstr(kExprI16x8ExtractLaneU), 0,
+ kExprLocalGet, 2,
+ ...SimdInstr(kExprI16x8ExtractLaneU), 4,
+ ])
+ .exportFunc();
+
+const wasm = builder.instantiate().exports;
+
+function testVectorNarrow(values, min, max, func) {
+ // Clamp signed source values to the destination range [min, max].
+ for (const left of values) {
+ for (const right of values) {
+ assertEquals(
+ [Math.max(min, Math.min(max, left)),
+ Math.max(min, Math.min(max, right))],
+ func(left, right), `left ${left}, right ${right}`);
+ }
+ }
+}
+
+// i16x8 -> i8x16.
+testVectorNarrow(int16_array, -128, 127, wasm.i8x16_narrow_s);
+testVectorNarrow(int16_array, 0, 255, wasm.i8x16_narrow_u);
+
+// i32x4 -> i16x8.
+testVectorNarrow(int32_array, -32768, 32767, wasm.i16x8_narrow_s);
+testVectorNarrow(int32_array, 0, 65535, wasm.i16x8_narrow_u);
diff --git a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
index 38992879d48..0971820d5d8 100644
--- a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
+++ b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
@@ -746,11 +746,12 @@ let kExprI64AtomicCompareExchange32U = 0x4e;
// Atomic GC opcodes (shared-everything-threads).
const kExprPause = 0x04;
-// TODO(manoskouk): These are just placeholders, adjust them when the spec
+// TODO(manoskouk): These four are just placeholders, adjust them when the spec
// defines them.
const kExprStructWait = 0x05;
const kExprWaitqueueNotify = 0x06;
const kExprWaitqueueNew = 0x07;
+const kExprArrayWait = 0x08;
const kExprPublish = 0x0f;
const kExprStructAtomicGet = 0x5c;
const kExprStructAtomicGetS = 0x5d;
diff --git a/deps/v8/test/mjsunit/wasm/wide-add.js b/deps/v8/test/mjsunit/wasm/wide-add.js
index fcbe7f85228..be180ab8628 100644
--- a/deps/v8/test/mjsunit/wasm/wide-add.js
+++ b/deps/v8/test/mjsunit/wasm/wide-add.js
@@ -400,6 +400,70 @@ function testBigIntAddLoops() {
}
}
+function testAdd3DroppedCarry() {
+ let builder = new WasmModuleBuilder();
+ builder.addFunction("add3_dropped_carry", makeSig([kWasmI64, kWasmI64, kWasmI64], [kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprLocalGet, 1, // b
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprLocalGet, 2, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprDrop, // drop carry-out, return low sum
+ ]);
+
+ let instance = builder.instantiate();
+ let f = instance.exports.add3_dropped_carry;
+
+ const max = 0xffffffffffffffffn;
+ assertEquals(6n, f(1n, 2n, 3n));
+ assertEquals(4n, f(max, 2n, 3n));
+ assertEquals(1n, f(max - 1n, 1n, 2n));
+ assertEquals(0n, f(max, 2n, max));
+}
+
+function testAdd3MultiUseIntermediate() {
+ let builder = new WasmModuleBuilder();
+ // Computes (a + b) and ((a + b) + c), returning (final_sum, final_carry, intermediate_extra).
+ // Projection(0) of (a + b) is consumed by an i64.add before the second add128,
+ // making its saturated_use_count in the output graph > 0.
+ // Therefore, TryMatchAdd3 must reject the fusion, leaving two separate additions.
+ builder.addFunction("add3_multi_use", makeSig([kWasmI64, kWasmI64, kWasmI64], [kWasmI64, kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addLocals(kWasmI64, 3) // local 3: al, local 4: ah, local 5: al_extra
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprLocalGet, 1, // b
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprLocalSet, 4, // ah = Projection(1)
+ kExprLocalTee, 3, // al = Projection(0)
+ kExprI64Const, 1,
+ kExprI64Add,
+ kExprLocalSet, 5, // local 5 = al + 1
+ kExprLocalGet, 3, // al
+ kExprLocalGet, 4, // ah
+ kExprLocalGet, 2, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprLocalGet, 5, // return [final_sum, final_carry, al + 1]
+ ]);
+
+ let instance = builder.instantiate();
+ let f = instance.exports.add3_multi_use;
+
+ const max = 0xffffffffffffffffn;
+ assertEquals([60n, 0n, 31n], f(10n, 20n, 30n));
+ assertEquals([5n, 1n, 2n], f(max, 2n, 4n));
+}
+
testAdd3Pattern();
testAdd3Constants();
+testAdd3DroppedCarry();
+testAdd3MultiUseIntermediate();
testBigIntAddLoops();
diff --git a/deps/v8/test/mkgrokdump/BUILD.gn b/deps/v8/test/mkgrokdump/BUILD.gn
index f0167070a09..28bcfd0e7f3 100644
--- a/deps/v8/test/mkgrokdump/BUILD.gn
+++ b/deps/v8/test/mkgrokdump/BUILD.gn
@@ -17,6 +17,7 @@ v8_executable("mkgrokdump") {
deps = [
"../..:v8",
+ "../..:v8_internal_headers",
"../..:v8_libbase",
"../..:v8_libplatform",
"//build/win:default_exe_manifest",
diff --git a/deps/v8/test/test262/.lint-vpython3 b/deps/v8/test/test262/.lint-vpython3
deleted file mode 100644
index 6426422a7b1..00000000000
--- a/deps/v8/test/test262/.lint-vpython3
+++ /dev/null
@@ -1,4 +0,0 @@
-wheel: <
- name: "infra/python/wheels/pyyaml/${vpython_platform}"
- version: "version:5.4.1.chromium.1"
->
\ No newline at end of file
diff --git a/deps/v8/test/test262/PRESUBMIT.py b/deps/v8/test/test262/PRESUBMIT.py
index 66d3e0a392c..2a6a53aa8f1 100644
--- a/deps/v8/test/test262/PRESUBMIT.py
+++ b/deps/v8/test/test262/PRESUBMIT.py
@@ -13,7 +13,7 @@ USE_PYTHON3 = True
def _CheckLint(input_api, output_api):
root = pathlib.Path(input_api.PresubmitLocalPath())
- vpython_spec = root / '.lint-vpython3'
+ vpython_spec = root / 'lint-vpython.toml'
workdir = root / 'data'
lint_exe = workdir / 'tools' / 'lint' / 'lint.py'
test_path = workdir / '..' / 'local-tests' / 'test'
diff --git a/deps/v8/test/test262/lint-vpython.toml b/deps/v8/test/test262/lint-vpython.toml
new file mode 100644
index 00000000000..47a024b0394
--- /dev/null
+++ b/deps/v8/test/test262/lint-vpython.toml
@@ -0,0 +1,9 @@
+# Copyright 2026 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.
+
+requires-python = '>=3.11,<3.12'
+dependencies = [
+ 'pip==25.0.1',
+ 'pyyaml==5.4.1+chromium.1',
+]
diff --git a/deps/v8/test/test262/lint-vpython.toml.uv.lock b/deps/v8/test/test262/lint-vpython.toml.uv.lock
new file mode 100644
index 00000000000..d8192219382
--- /dev/null
+++ b/deps/v8/test/test262/lint-vpython.toml.uv.lock
@@ -0,0 +1,19 @@
+pip==25.0.1 \
+ --hash=sha256:c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f
+pyyaml==5.4.1+chromium.1 \
+ --hash=sha256:30943bf7ffc77849ab34b0c9a0bfdd2841d6cfef80a048443088c3981c3b7454 \
+ --hash=sha256:30943bf7ffc77849ab34b0c9a0bfdd2841d6cfef80a048443088c3981c3b7454 \
+ --hash=sha256:34de1c37474ed237b506bed193c3aa961136fb6c56d43c731b639a4658a561c7 \
+ --hash=sha256:3bb84571b42414183e96cc560b602c0b907174dc2ca45bfe28e53371d34a3573 \
+ --hash=sha256:3bf690dd33f9adb2493b54eed0eccedbb5dac7c38977dafbd6c5aaff4c2b9e72 \
+ --hash=sha256:4db0e513d46d3feedff69b33fb4093a899396b6795b790d9b1a9ed84c9de9b83 \
+ --hash=sha256:5cd00e9800df4255d79711cdfd039d957c5a06521ee6e4068efceca9ce09c333 \
+ --hash=sha256:5ef917f3c0447944e3c6a2d6feb7e4c96cadc912436e0bec593d6676438723e9 \
+ --hash=sha256:846e35c9c099b8d9a0b3c4c37444ef38dc9fbf9596f485565cdfa8b6bf33b8a4 \
+ --hash=sha256:9626a7a5bbf3ba01f18eeb6dab7e1a8218bc554a5425103335ed726421f16dac \
+ --hash=sha256:a757e3dbf41d474b343a1c9300051aad6857ba811a5b0844b229c9a81302b3e4 \
+ --hash=sha256:d3624a91bf9acba3a3753052056d59012ee303bba33685d9332077d0029fadbf \
+ --hash=sha256:d3624a91bf9acba3a3753052056d59012ee303bba33685d9332077d0029fadbf \
+ --hash=sha256:d901525f60a95a76c9c7fb87968355e9c76d88b538a84b7319b37219bfa4f37c \
+ --hash=sha256:e0f28dad378280bf0bfb1d3019c8b1dee1894f138f09643a10362235d3495be1 \
+ --hash=sha256:ed50a1341d0580c1ee4f8e381beb56d141df93ab1690fbe9d6b49df55215f318
diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status
index 7af617325d1..5795e84776f 100644
--- a/deps/v8/test/test262/test262.status
+++ b/deps/v8/test/test262/test262.status
@@ -768,7 +768,6 @@
# Roll-watcher patch
[ALWAYS, {
'language/destructuring/binding/keyed-destructuring-property-reference-target-evaluation-order-with-bindings': [SKIP],
- 'language/expressions/delete/super-property-uninitialized-this': [SKIP],
}],
# End roll-watcher patch
####
@@ -1243,4 +1242,18 @@
}],
# End roll-watcher patch
####
+
+####
+# Roll-watcher patch
+[ALWAYS, {
+ 'intl402/Locale/constructor-options-firstDayOfWeek-valid': [SKIP],
+ 'intl402/Locale/constructor-unicode-extension-uvalue-yes': [SKIP],
+ 'intl402/Locale/prototype/calendar/canonicalize-case': [SKIP],
+ 'intl402/Locale/prototype/collation/canonicalize-case': [SKIP],
+ 'intl402/Locale/prototype/firstDayOfWeek/valid-id': [SKIP],
+ 'intl402/Locale/prototype/firstDayOfWeek/valid-options': [SKIP],
+ 'intl402/Locale/prototype/numberingSystem/canonicalize-case': [SKIP],
+}],
+# End roll-watcher patch
+####
]
diff --git a/deps/v8/test/unittests/BUILD.gn b/deps/v8/test/unittests/BUILD.gn
index 06428824029..bf8dfc2ee23 100644
--- a/deps/v8/test/unittests/BUILD.gn
+++ b/deps/v8/test/unittests/BUILD.gn
@@ -349,6 +349,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"d8/memory-access-information-unittest.cc",
"date/date-cache-unittest.cc",
"date/date-unittest.cc",
+ "debug/debug-block-list-unittest.cc",
"debug/debug-property-iterator-unittest.cc",
"debug/debug-scope-info-unittest.cc",
"deoptimizer/deoptimization-unittest.cc",
@@ -500,12 +501,14 @@ v8_cluster_source_set("v8_unittests_sources") {
"parser/unicode-helpers.cc",
"parser/unicode-helpers.h",
"profiler/circular-queue-unittest.cc",
+ "profiler/heap-snapshot-scopes-unittest.cc",
"profiler/heap-snapshot-utils.cc",
"profiler/heap-snapshot-utils.h",
"profiler/output-stream-writer-unittest.cc",
"profiler/strings-storage-unittest.cc",
"regexp/regexp-unittest.cc",
"regress/regress-536271629-unittest.cc",
+ "regress/regress-568831099-unittest.cc",
"regress/regress-crbug-1041240-unittest.cc",
"regress/regress-crbug-1056054-unittest.cc",
"regress/regress-crbug-938251-unittest.cc",
@@ -649,6 +652,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"compiler/state-values-utils-unittest.cc",
"compiler/turboshaft/call-runtime-unittest.cc",
"compiler/turboshaft/control-flow-unittest.cc",
+ "compiler/turboshaft/instruction-selection-normalization-reducer-unittest.cc",
"compiler/turboshaft/late-load-elimination-reducer-unittest.cc",
"compiler/turboshaft/load-store-address-hoisting-unittest.cc",
"compiler/turboshaft/loop-unrolling-analyzer-unittest.cc",
@@ -704,6 +708,8 @@ v8_cluster_source_set("v8_unittests_sources") {
"wasm/wasm-compile-module.h",
"wasm/wasm-compiler-unittest.cc",
"wasm/wasm-disassembler-unittest-bad-name-section.wasm.inc",
+ "wasm/wasm-disassembler-unittest-fp16.wasm.inc",
+ "wasm/wasm-disassembler-unittest-fp16.wat.inc",
"wasm/wasm-disassembler-unittest-gc.wasm.inc",
"wasm/wasm-disassembler-unittest-gc.wat.inc",
"wasm/wasm-disassembler-unittest-mvp.wasm.inc",
@@ -1025,6 +1031,7 @@ v8_executable("generate-bytecode-expectations") {
deps = [
"../..:v8",
+ "../..:v8_internal_headers",
"../..:v8_libbase",
"../..:v8_libplatform",
"//build/win:default_exe_manifest",
diff --git a/deps/v8/test/unittests/api/access-check-unittest.cc b/deps/v8/test/unittests/api/access-check-unittest.cc
index 94749746616..4a7690edd4c 100644
--- a/deps/v8/test/unittests/api/access-check-unittest.cc
+++ b/deps/v8/test/unittests/api/access-check-unittest.cc
@@ -425,7 +425,7 @@ v8::Intercepted MethodGetter(Local<Name> property,
Isolate* isolate = info.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
- Local<External> data = info.Data().As<External>();
+ Local<External> data = info.DataV2().As<External>();
Local<FunctionTemplate>& function_template =
*reinterpret_cast<Local<FunctionTemplate>*>(
data->Value(kFunctionTemplateTag));
diff --git a/deps/v8/test/unittests/api/api-wasm-unittest.cc b/deps/v8/test/unittests/api/api-wasm-unittest.cc
index 0eb4bd46614..03d25144825 100644
--- a/deps/v8/test/unittests/api/api-wasm-unittest.cc
+++ b/deps/v8/test/unittests/api/api-wasm-unittest.cc
@@ -88,7 +88,7 @@ void WasmStreamingCallbackTestCallbackIsCalled(
i::Handle<i::Object> global_handle =
reinterpret_cast<i::Isolate*>(info.GetIsolate())
->global_handles()
- ->Create(*Utils::OpenDirectHandle(*info.Data()));
+ ->Create(*Utils::OpenDirectHandle(*info.DataV2()));
i::GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
WasmStreamingTestFinalizer,
WeakCallbackType::kParameter);
@@ -98,7 +98,7 @@ void WasmStreamingCallbackTestFinishWithSuccess(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->OnBytesReceived(kMinimalWasmModuleBytes,
arraysize(kMinimalWasmModuleBytes));
streaming->Finish(WasmStreaming::ModuleCachingCallback{});
@@ -108,7 +108,7 @@ void WasmStreamingCallbackTestFinishWithFailure(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->Finish(WasmStreaming::ModuleCachingCallback{});
}
@@ -116,7 +116,7 @@ void WasmStreamingCallbackTestAbortWithReject(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->Abort(Object::New(info.GetIsolate()));
}
@@ -124,7 +124,7 @@ void WasmStreamingCallbackTestAbortNoReject(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->Abort({});
}
@@ -132,7 +132,7 @@ void WasmStreamingCallbackTestOnBytesReceived(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
// The first bytes of the WebAssembly magic word.
const uint8_t bytes[]{0x00, 0x61, 0x73};
@@ -143,7 +143,7 @@ void WasmStreamingMoreFunctionsCanBeSerializedCallback(
const FunctionCallbackInfo<Value>& info) {
CHECK(i::ValidateCallbackInfo(info));
std::shared_ptr<WasmStreaming> streaming =
- WasmStreaming::Unpack(info.GetIsolate(), info.Data());
+ WasmStreaming::Unpack(info.GetIsolate(), info.DataV2());
streaming->SetMoreFunctionsCanBeSerializedCallback([](CompiledWasmModule) {});
}
diff --git a/deps/v8/test/unittests/api/v8-array-buffer-unittest.cc b/deps/v8/test/unittests/api/v8-array-buffer-unittest.cc
index 4aaec1617f6..0eb69a29129 100644
--- a/deps/v8/test/unittests/api/v8-array-buffer-unittest.cc
+++ b/deps/v8/test/unittests/api/v8-array-buffer-unittest.cc
@@ -4,6 +4,11 @@
#include "include/v8-array-buffer.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <span>
+
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -36,5 +41,24 @@ TEST_F(ArrayBufferTest, TransferWithDetachKey) {
EXPECT_EQ(ab->ByteLength(), 0u);
}
+TEST_F(ArrayBufferTest, BackingStoreByteSpan) {
+ constexpr size_t kByteLength = 8;
+
+ std::unique_ptr<BackingStore> backing_store =
+ ArrayBuffer::NewBackingStore(isolate(), kByteLength);
+
+ std::span<uint8_t> span = backing_store->ByteSpan();
+
+ EXPECT_EQ(span.data(), static_cast<uint8_t*>(backing_store->Data()));
+ EXPECT_EQ(span.size(), backing_store->ByteLength());
+
+ std::fill(span.begin(), span.end(), uint8_t{0xAB});
+ const auto* data = static_cast<const uint8_t*>(backing_store->Data());
+
+ for (size_t i = 0; i < kByteLength; ++i) {
+ EXPECT_EQ(uint8_t{0xAB}, data[i]);
+ }
+}
+
} // namespace
} // namespace v8
diff --git a/deps/v8/test/unittests/api/v8-object-unittest.cc b/deps/v8/test/unittests/api/v8-object-unittest.cc
index d2f137166f2..5b84a238b0d 100644
--- a/deps/v8/test/unittests/api/v8-object-unittest.cc
+++ b/deps/v8/test/unittests/api/v8-object-unittest.cc
@@ -62,7 +62,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
[](const FunctionCallbackInfo<Value>& info) {
++call_count;
Local<Context> prototype_context = *reinterpret_cast<Local<Context>*>(
- info.Data().As<External>()->Value(kContextTag));
+ info.DataV2().As<External>()->Value(kContextTag));
EXPECT_EQ(prototype_context, info.GetIsolate()->GetCurrentContext());
},
External::New(isolate(), &prototype_context, kContextTag), signature);
@@ -129,7 +129,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
[](const FunctionCallbackInfo<Value>& info) {
++call_count;
Local<Context> receiver_context = *reinterpret_cast<Local<Context>*>(
- info.Data().As<External>()->Value(kContextTag));
+ info.DataV2().As<External>()->Value(kContextTag));
EXPECT_EQ(receiver_context, info.GetIsolate()->GetCurrentContext());
},
External::New(isolate(), &receiver_context, kContextTag), signature);
@@ -180,7 +180,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
[](const FunctionCallbackInfo<Value>& info) {
++call_count;
Local<Context> interface_context = *reinterpret_cast<Local<Context>*>(
- info.Data().As<External>()->Value(kContextTag));
+ info.DataV2().As<External>()->Value(kContextTag));
EXPECT_EQ(interface_context, info.GetIsolate()->GetCurrentContext());
},
External::New(isolate(), &interface_context, kContextTag),
diff --git a/deps/v8/test/unittests/base/region-allocator-unittest.cc b/deps/v8/test/unittests/base/region-allocator-unittest.cc
index 3fadc225f29..71674c42078 100644
--- a/deps/v8/test/unittests/base/region-allocator-unittest.cc
+++ b/deps/v8/test/unittests/base/region-allocator-unittest.cc
@@ -372,6 +372,41 @@ TEST(RegionAllocatorTest, TrimRegion) {
CHECK_EQ(ra.AllocateRegion(kSize), kBegin);
}
+TEST(RegionAllocatorTest, FreeRegionReportsMergedFreeRegion) {
+ const size_t kPageSize = 4 * KB;
+ const size_t kPageCount = 8;
+ const size_t kSize = kPageSize * kPageCount;
+ const Address kBegin = static_cast<Address>(kPageSize * 153);
+
+ RegionAllocator ra(kBegin, kSize, kPageSize);
+
+ // Allocate the whole region page by page.
+ for (size_t i = 0; i < kPageCount; i++) {
+ CHECK_EQ(ra.AllocateRegion(kPageSize), kBegin + kPageSize * i);
+ }
+
+ // A freed page with allocated neighbours is a free region of its own.
+ AddressRegion free_region;
+ CHECK_EQ(ra.FreeRegion(kBegin + 3 * kPageSize, &free_region), kPageSize);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 3 * kPageSize, kPageSize));
+
+ // Freeing its neighbours merges them into it, on either side.
+ CHECK_EQ(ra.FreeRegion(kBegin + 4 * kPageSize, &free_region), kPageSize);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 3 * kPageSize, 2 * kPageSize));
+ CHECK_EQ(ra.FreeRegion(kBegin + 2 * kPageSize, &free_region), kPageSize);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 2 * kPageSize, 3 * kPageSize));
+
+ // Freeing the page between two free regions merges all three.
+ CHECK_EQ(ra.FreeRegion(kBegin + 6 * kPageSize, &free_region), kPageSize);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 6 * kPageSize, kPageSize));
+ CHECK_EQ(ra.FreeRegion(kBegin + 5 * kPageSize, &free_region), kPageSize);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 2 * kPageSize, 5 * kPageSize));
+
+ // Nothing to free: the out parameter is left alone.
+ CHECK_EQ(ra.FreeRegion(kBegin + 5 * kPageSize, &free_region), 0);
+ CHECK_EQ(free_region, AddressRegion(kBegin + 2 * kPageSize, 5 * kPageSize));
+}
+
TEST(RegionAllocatorTest, TryGrowRegion) {
const size_t kPageSize = 4 * KB;
const size_t kPageCount = 60;
diff --git a/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-selector-arm64-unittest.cc
index dfd84c8f8e4..03b0eced4c8 100644
--- a/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-selector-arm64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-selector-arm64-unittest.cc
@@ -3008,6 +3008,220 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
#if V8_ENABLE_WEBASSEMBLY
+namespace {
+
+struct SIMDIntNarrowingInst {
+ const char* name;
+ TSBinop operation;
+ ArchOpcode narrow_opcode;
+ ArchOpcode narrow2_opcode;
+ int lane_size;
+};
+
+std::ostream& operator<<(std::ostream& os, const SIMDIntNarrowingInst& inst) {
+ return os << inst.name;
+}
+
+const SIMDIntNarrowingInst kSIMDIntNarrowingInstructions[] = {
+ {"I16x8SConvertI32x4", TSBinop::kI16x8SConvertI32x4, kArm64Sqxtn,
+ kArm64Sqxtn2, 32},
+ {"I16x8UConvertI32x4", TSBinop::kI16x8UConvertI32x4, kArm64Sqxtun,
+ kArm64Sqxtun2, 32},
+ {"I8x16SConvertI16x8", TSBinop::kI8x16SConvertI16x8, kArm64Sqxtn,
+ kArm64Sqxtn2, 16},
+ {"I8x16UConvertI16x8", TSBinop::kI8x16UConvertI16x8, kArm64Sqxtun,
+ kArm64Sqxtun2, 16},
+};
+
+} // namespace
+
+using TurboshaftInstructionSelectorSIMDIntNarrowingTest =
+ TurboshaftInstructionSelectorTestWithParam<SIMDIntNarrowingInst>;
+
+TEST_P(TurboshaftInstructionSelectorSIMDIntNarrowingTest, Parameter) {
+ const SIMDIntNarrowingInst param = GetParam();
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
+ MachineType::Simd128());
+ const V<Simd128> low = m.Parameter(0);
+ const V<Simd128> high = m.Parameter(1);
+ const OpIndex result = m.Emit(param.operation, low, high);
+ m.Return(result);
+ const Stream s = m.Build();
+
+ ASSERT_EQ(2U, s.size());
+
+ EXPECT_EQ(param.narrow_opcode, s[0]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[0]->opcode())));
+ ASSERT_EQ(1U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(low), s.ToVreg(s[0]->InputAt(0)));
+
+ EXPECT_EQ(param.narrow2_opcode, s[1]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[1]->opcode())));
+ ASSERT_EQ(2U, s[1]->InputCount());
+ ASSERT_EQ(1U, s[1]->OutputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(high), s.ToVreg(s[1]->InputAt(1)));
+ EXPECT_EQ(s.ToVreg(result), s.ToVreg(s[1]->Output()));
+ EXPECT_TRUE(s.IsSameAsInput(s[1]->Output(), 0));
+}
+
+INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
+ TurboshaftInstructionSelectorSIMDIntNarrowingTest,
+ ::testing::ValuesIn(kSIMDIntNarrowingInstructions));
+
+struct SIMDShiftInst {
+ const char* shift_constructor_name;
+ TSBinop shift_operation;
+ ArchOpcode target_opcode;
+ ArchOpcode shift_opcode;
+ const int lane_size;
+};
+
+std::ostream& operator<<(std::ostream& os, const SIMDShiftInst& inst) {
+ return os << inst.shift_constructor_name;
+}
+
+static const SIMDShiftInst kSIMDShiftTests[] = {
+ {"I64x2Shl", TSBinop::kI64x2Shl, kArm64IShl, kArm64SShl, 64},
+ {"I32x4Shl", TSBinop::kI32x4Shl, kArm64IShl, kArm64SShl, 32},
+ {"I16x8Shl", TSBinop::kI16x8Shl, kArm64IShl, kArm64SShl, 16},
+ {"I8x16Shl", TSBinop::kI8x16Shl, kArm64IShl, kArm64SShl, 8},
+
+ {"I64x2ShrS", TSBinop::kI64x2ShrS, kArm64IShrS, kArm64SShl, 64},
+ {"I32x4ShrS", TSBinop::kI32x4ShrS, kArm64IShrS, kArm64SShl, 32},
+ {"I16x8ShrS", TSBinop::kI16x8ShrS, kArm64IShrS, kArm64SShl, 16},
+ {"I8x16ShrS", TSBinop::kI8x16ShrS, kArm64IShrS, kArm64SShl, 8},
+
+ {"I64x2ShrU", TSBinop::kI64x2ShrU, kArm64IShrU, kArm64UShl, 64},
+ {"I32x4ShrU", TSBinop::kI32x4ShrU, kArm64IShrU, kArm64UShl, 32},
+ {"I16x8ShrU", TSBinop::kI16x8ShrU, kArm64IShrU, kArm64UShl, 16},
+ {"I8x16ShrU", TSBinop::kI8x16ShrU, kArm64IShrU, kArm64UShl, 8},
+};
+
+using TurboshaftInstructionSelectorSIMDShiftTest =
+ TurboshaftInstructionSelectorTestWithParam<SIMDShiftInst>;
+
+TEST_P(TurboshaftInstructionSelectorSIMDShiftTest, NormalImmediate) {
+ const SIMDShiftInst param = GetParam();
+ for (int immediate : {2, param.lane_size + 2}) {
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ V<Simd128> input = m.Parameter(0);
+ m.Return(m.Emit(param.shift_operation, input, m.Int32Constant(immediate)));
+ const Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(param.target_opcode, s[0]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[0]->opcode())));
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(input), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
+ EXPECT_EQ(2, s.ToInt32(s[0]->InputAt(1)));
+ }
+}
+
+TEST_P(TurboshaftInstructionSelectorSIMDShiftTest, ZeroShift) {
+ const SIMDShiftInst param = GetParam();
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ m.Return(m.Emit(param.shift_operation, m.Parameter(0), m.Int32Constant(0)));
+ const Stream s = m.Build();
+
+ ASSERT_EQ(0U, s.size());
+}
+
+TEST_P(TurboshaftInstructionSelectorSIMDShiftTest, LaneWidthShift) {
+ const SIMDShiftInst param = GetParam();
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ m.Return(m.Emit(param.shift_operation, m.Parameter(0),
+ m.Int32Constant(param.lane_size)));
+ const Stream s = m.Build();
+
+ ASSERT_EQ(0U, s.size());
+}
+
+TEST_P(TurboshaftInstructionSelectorSIMDShiftTest,
+ VariableShiftMasksAndDuplicatesCount) {
+ const SIMDShiftInst param = GetParam();
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
+ MachineType::Int32());
+ V<Simd128> input = m.Parameter(0);
+ V<Word32> count = m.Parameter(1);
+ m.Return(m.Emit(param.shift_operation, input, count));
+ const Stream s = m.Build();
+
+ const bool is_left_shift = param.target_opcode == kArm64IShl;
+ ASSERT_EQ(is_left_shift ? 3U : 4U, s.size());
+
+ EXPECT_EQ(kArm64And32, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(count), s.ToVreg(s[0]->InputAt(0)));
+ ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
+ EXPECT_EQ(param.lane_size - 1, s.ToInt32(s[0]->InputAt(1)));
+
+ EXPECT_EQ(kArm64ISplat, s[1]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[1]->opcode())));
+ ASSERT_EQ(1U, s[1]->InputCount());
+ ASSERT_EQ(1U, s[1]->OutputCount());
+ EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+
+ size_t shift_index = 2;
+ if (!is_left_shift) {
+ EXPECT_EQ(kArm64INeg, s[2]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[2]->opcode())));
+ ASSERT_EQ(1U, s[2]->InputCount());
+ ASSERT_EQ(1U, s[2]->OutputCount());
+ EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0)));
+ shift_index = 3;
+ }
+
+ EXPECT_EQ(param.shift_opcode, s[shift_index]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[shift_index]->opcode())));
+ ASSERT_EQ(2U, s[shift_index]->InputCount());
+ ASSERT_EQ(1U, s[shift_index]->OutputCount());
+ EXPECT_EQ(s.ToVreg(input), s.ToVreg(s[shift_index]->InputAt(0)));
+ EXPECT_EQ(s.ToVreg(s[shift_index - 1]->Output()),
+ s.ToVreg(s[shift_index]->InputAt(1)));
+}
+
+class TurboshaftInstructionSelectorSIMDShrSTest
+ : public TurboshaftInstructionSelectorTestWithParam<SIMDShiftInst> {};
+
+TEST_P(TurboshaftInstructionSelectorSIMDShrSTest, ShrSByWidthMinusOne) {
+ const SIMDShiftInst param = GetParam();
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ V<Simd128> input = m.Parameter(0);
+ m.Return(m.Emit(param.shift_operation, input,
+ m.Int32Constant(param.lane_size - 1)));
+ const Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64ILtS, s[0]->arch_opcode());
+ EXPECT_EQ(param.lane_size,
+ LaneSizeBits(LaneSizeField::decode(s[0]->opcode())));
+ ASSERT_EQ(1U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(input), s.ToVreg(s[0]->InputAt(0)));
+}
+
+INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
+ TurboshaftInstructionSelectorSIMDShiftTest,
+ ::testing::ValuesIn(kSIMDShiftTests));
+
+INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
+ TurboshaftInstructionSelectorSIMDShrSTest,
+ ::testing::Values(kSIMDShiftTests[4],
+ kSIMDShiftTests[5],
+ kSIMDShiftTests[6],
+ kSIMDShiftTests[7]));
+
TEST_F(TurboshaftInstructionSelectorTest, I32x4DotI8x16I7x16AddS) {
StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
MachineType::Simd128(), MachineType::Simd128());
@@ -7260,7 +7474,7 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[1]->arch_opcode());
EXPECT_EQ(kMode_MRR, s[1]->addressing_mode());
- EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[1]->opcode()),
+ EXPECT_EQ(RecordWriteModeField::decode(s[1]->opcode()),
RecordWriteMode::kValueIsAny);
}
@@ -10257,9 +10471,9 @@ TEST_P(TurboshaftInstructionSelectorSIMDSubFamilyTest, wasmSimdSubFamilyTest) {
}
TEST_F(TurboshaftInstructionSelectorTest, SimdShiftToAdd) {
- {
+ for (int shift : {1, 8 + 1}) {
StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
- m.Return(m.I8x16Shl(m.Parameter(0), m.Int32Constant(1)));
+ m.Return(m.I8x16Shl(m.Parameter(0), m.Int32Constant(shift)));
Stream s = m.Build();
EXPECT_EQ(1U, s.size());
EXPECT_EQ(kArm64IAdd, s[0]->arch_opcode());
@@ -10267,9 +10481,9 @@ TEST_F(TurboshaftInstructionSelectorTest, SimdShiftToAdd) {
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0)));
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(1)));
}
- {
+ for (int shift : {1, 16 + 1}) {
StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
- m.Return(m.I16x8Shl(m.Parameter(0), m.Int32Constant(1)));
+ m.Return(m.I16x8Shl(m.Parameter(0), m.Int32Constant(shift)));
Stream s = m.Build();
EXPECT_EQ(1U, s.size());
EXPECT_EQ(kArm64IAdd, s[0]->arch_opcode());
@@ -10277,9 +10491,9 @@ TEST_F(TurboshaftInstructionSelectorTest, SimdShiftToAdd) {
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0)));
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(1)));
}
- {
+ for (int shift : {1, 32 + 1}) {
StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
- m.Return(m.I32x4Shl(m.Parameter(0), m.Int32Constant(1)));
+ m.Return(m.I32x4Shl(m.Parameter(0), m.Int32Constant(shift)));
Stream s = m.Build();
EXPECT_EQ(1U, s.size());
EXPECT_EQ(kArm64IAdd, s[0]->arch_opcode());
@@ -10287,9 +10501,9 @@ TEST_F(TurboshaftInstructionSelectorTest, SimdShiftToAdd) {
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0)));
EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(1)));
}
- {
+ for (int shift : {1, 64 + 1}) {
StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
- m.Return(m.I64x2Shl(m.Parameter(0), m.Int32Constant(1)));
+ m.Return(m.I64x2Shl(m.Parameter(0), m.Int32Constant(shift)));
Stream s = m.Build();
EXPECT_EQ(1U, s.size());
EXPECT_EQ(kArm64IAdd, s[0]->arch_opcode());
@@ -10661,4 +10875,38 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
}
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ OpIndex high = m.Projection(res, 1);
+ m.Return(m.Word64Add(low, high));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArm64Add64_3, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(2U, s[0]->OutputCount());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3UnusedHigh) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ m.Return(low);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Add64_3, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+}
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/common-operator-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
index c8ed8b164d3..c71adaf3b61 100644
--- a/deps/v8/test/unittests/compiler/common-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/common-operator-unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/common-operator.h"
+
#include <limits>
-#include "src/compiler/common-operator.h"
+#include "src/compiler/frame-states.h"
#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
#include "src/compiler/operator-properties.h"
+#include "src/compiler/operator.h"
#include "test/unittests/test-utils.h"
namespace v8 {
@@ -392,6 +394,49 @@ TEST_F(CommonOperatorTest, Projection) {
}
}
+TEST_F(CommonOperatorTest, DeoptimizeParameters) {
+ FeedbackSource feedback1;
+ FeedbackSource feedback2(IndirectHandle<FeedbackVector>(), FeedbackSlot(0));
+ DeoptimizeParameters p1(DeoptimizeReason::kNotASmi, feedback1);
+ DeoptimizeParameters p2(DeoptimizeReason::kNotASmi, feedback1);
+ DeoptimizeParameters p3(DeoptimizeReason::kWrongMap, feedback1);
+ DeoptimizeParameters p4(DeoptimizeReason::kNotASmi, feedback2);
+ EXPECT_EQ(p1, p2);
+ EXPECT_EQ(hash_value(p1), hash_value(p2));
+ EXPECT_NE(p1, p3);
+ EXPECT_NE(hash_value(p1), hash_value(p3));
+ EXPECT_NE(p1, p4);
+ EXPECT_NE(hash_value(p1), hash_value(p4));
+}
+
+TEST_F(CommonOperatorTest, FrameStateInfo) {
+ const FrameStateFunctionInfo* function_info1 =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 0, 0, 0, {}, {});
+ const FrameStateFunctionInfo* function_info2 =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kConstructInvokeStub, 0, 0, 0, {}, {});
+ const FrameStateFunctionInfo* function_info3 =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 1, 0, 0, {}, {});
+ FrameStateInfo state1(BytecodeOffset(1), OutputFrameStateCombine::Ignore(),
+ function_info1);
+ FrameStateInfo state2(BytecodeOffset(1), OutputFrameStateCombine::Ignore(),
+ function_info1);
+ FrameStateInfo state3(BytecodeOffset(2), OutputFrameStateCombine::Ignore(),
+ function_info1);
+ FrameStateInfo state4(BytecodeOffset(1), OutputFrameStateCombine::Ignore(),
+ function_info2);
+ FrameStateInfo state5(BytecodeOffset(1), OutputFrameStateCombine::Ignore(),
+ function_info3);
+ EXPECT_EQ(state1, state2);
+ EXPECT_EQ(hash_value(state1), hash_value(state2));
+ EXPECT_NE(state1, state3);
+ EXPECT_NE(state1, state4);
+ EXPECT_NE(state1, state5);
+ EXPECT_EQ(hash_value(state1), hash_value(state5));
+}
+
} // namespace
} // namespace common_operator_unittest
} // namespace compiler
diff --git a/deps/v8/test/unittests/compiler/compiler-unittest.cc b/deps/v8/test/unittests/compiler/compiler-unittest.cc
index e03d1c961f1..63ab3a6d48c 100644
--- a/deps/v8/test/unittests/compiler/compiler-unittest.cc
+++ b/deps/v8/test/unittests/compiler/compiler-unittest.cc
@@ -1151,5 +1151,58 @@ TEST_F(BackgroundMergeTest, GCDuringMerge) {
}
}
+TEST_F(BackgroundMergeTest, MergeWithEval) {
+ v8_flags.verify_code_merge = true;
+
+ HandleScope handle_scope(isolate());
+ const char* source =
+ "var f = () => {"
+ " 'use strict';"
+ " return eval('1');"
+ "};";
+ IndirectHandle<String> source_string =
+ isolate()
+ ->factory()
+ ->NewStringFromUtf8(base::CStrVector(source))
+ .ToHandleChecked();
+
+ ScriptCompiler::CompilationDetails compilation_details;
+ DirectHandle<SharedFunctionInfo> top_level_sfi =
+ Compiler::GetSharedFunctionInfoForScript(
+ isolate(), source_string, ScriptDetails(),
+ v8::ScriptCompiler::kNoCompileOptions,
+ ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE,
+ &compilation_details)
+ .ToHandleChecked();
+ DirectHandle<Script> old_script(Cast<Script>(top_level_sfi->script()),
+ isolate());
+
+ DirectHandle<JSFunction> top_level =
+ Factory::JSFunctionBuilder{isolate(), top_level_sfi,
+ isolate()->native_context()}
+ .Build();
+ DirectHandle<JSObject> global(isolate()->context()->global_object(),
+ isolate());
+ Execution::CallScript(isolate(), top_level, global,
+ isolate()->factory()->empty_fixed_array())
+ .Check();
+
+ DirectHandle<JSFunction> f = Cast<JSFunction>(
+ JSObject::GetProperty(isolate(), global, "f").ToHandleChecked());
+ Execution::Call(isolate(), f, global, {}).Check();
+
+ ScriptStreamingData streamed_source(
+ std::make_unique<DummySourceStream>(source),
+ v8::ScriptCompiler::StreamedSource::UTF8);
+ ScriptCompiler::CompilationDetails details;
+ streamed_source.task = std::make_unique<i::BackgroundCompileTask>(
+ &streamed_source, isolate(), ScriptType::kClassic,
+ ScriptCompiler::CompileOptions::kNoCompileOptions, &details);
+
+ streamed_source.task->RunOnMainThread(isolate());
+ streamed_source.task->FinalizeScript(isolate(), source_string,
+ ScriptDetails(), old_script);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/decompression-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/decompression-optimizer-unittest.cc
index ddb4e0ef7d8..74fa68bdb5d 100644
--- a/deps/v8/test/unittests/compiler/decompression-optimizer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/decompression-optimizer-unittest.cc
@@ -252,9 +252,13 @@ TEST_F(DecompressionOptimizerTest, TypedStateValues) {
constant_1);
Node* constant_2 =
graph()->NewNode(common()->HeapConstant(heap_constants[j]));
+ FrameStateFunctionInfo const* function_info =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 0, 0, 0, {}, {});
graph()->SetEnd(graph()->NewNode(
common()->FrameState(BytecodeOffset::None(),
- OutputFrameStateCombine::Ignore(), nullptr),
+ OutputFrameStateCombine::Ignore(),
+ function_info),
typed_state_values, typed_state_values, typed_state_values,
constant_2, UndefinedConstant(), graph()->start()));
diff --git a/deps/v8/test/unittests/compiler/ia32/turboshaft-instruction-selector-ia32-unittest.cc b/deps/v8/test/unittests/compiler/ia32/turboshaft-instruction-selector-ia32-unittest.cc
index 1f5fc7e309b..970545ae930 100644
--- a/deps/v8/test/unittests/compiler/ia32/turboshaft-instruction-selector-ia32-unittest.cc
+++ b/deps/v8/test/unittests/compiler/ia32/turboshaft-instruction-selector-ia32-unittest.cc
@@ -982,7 +982,7 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[0]->arch_opcode());
EXPECT_EQ(AtomicMemoryOrderField::decode(s[0]->opcode()),
AtomicMemoryOrder::kSeqCst);
- EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[0]->opcode()),
+ EXPECT_EQ(RecordWriteModeField::decode(s[0]->opcode()),
RecordWriteMode::kValueIsAny);
}
diff --git a/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc
index ce9c3b55940..a0a4e49edb9 100644
--- a/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc
@@ -111,9 +111,12 @@ class JSCallReducerTest : public TypedGraphTest {
}
Node* DummyFrameState() {
+ FrameStateFunctionInfo const* function_info =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 0, 0, 0, {}, {});
return graph()->NewNode(
common()->FrameState(BytecodeOffset{42},
- OutputFrameStateCombine::Ignore(), nullptr),
+ OutputFrameStateCombine::Ignore(), function_info),
graph()->start(), graph()->start(), graph()->start(), graph()->start(),
graph()->start(), graph()->start());
}
@@ -647,9 +650,12 @@ TEST_F(JSCallReducerTest, ConstructForwardAllArgsWithDeadParameters) {
graph()->NewNode(common()->DeadValue(MachineRepresentation::kTagged),
graph()->NewNode(common()->Dead()));
Node* outer_frame_state = DummyFrameState();
+ FrameStateFunctionInfo const* function_info =
+ common()->CreateFrameStateFunctionInfo(
+ FrameStateType::kUnoptimizedFunction, 0, 0, 0, {}, {});
Node* frame_state = graph()->NewNode(
common()->FrameState(BytecodeOffset::None(),
- OutputFrameStateCombine::Ignore(), nullptr),
+ OutputFrameStateCombine::Ignore(), function_info),
dead_value, graph()->start(), graph()->start(), graph()->start(),
graph()->start(), outer_frame_state);
diff --git a/deps/v8/test/unittests/compiler/loong64/turboshaft-instruction-selector-loong64-unittest.cc b/deps/v8/test/unittests/compiler/loong64/turboshaft-instruction-selector-loong64-unittest.cc
index 4fe0f84690a..3b217ddfd4f 100644
--- a/deps/v8/test/unittests/compiler/loong64/turboshaft-instruction-selector-loong64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/loong64/turboshaft-instruction-selector-loong64-unittest.cc
@@ -2146,7 +2146,7 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
EXPECT_EQ(kLoong64Add_d, s[0]->arch_opcode());
EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[1]->arch_opcode());
EXPECT_EQ(kMode_MRR, s[1]->addressing_mode());
- EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[1]->opcode()),
+ EXPECT_EQ(RecordWriteModeField::decode(s[1]->opcode()),
RecordWriteMode::kValueIsAny);
}
@@ -2172,4 +2172,38 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
}
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ OpIndex high = m.Projection(res, 1);
+ m.Return(m.Word64Add(low, high));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kLoong64Add64_3, s[0]->arch_opcode());
+ EXPECT_EQ(kLoong64Add_d, s[1]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(2U, s[0]->OutputCount());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3UnusedHigh) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ m.Return(low);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kLoong64Add64_3, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+}
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/mips64/turboshaft-instruction-selector-mips64-unittest.cc b/deps/v8/test/unittests/compiler/mips64/turboshaft-instruction-selector-mips64-unittest.cc
index b16c21d1968..7dd0a865972 100644
--- a/deps/v8/test/unittests/compiler/mips64/turboshaft-instruction-selector-mips64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/mips64/turboshaft-instruction-selector-mips64-unittest.cc
@@ -2108,10 +2108,44 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
EXPECT_EQ(kMips64Dadd, s[0]->arch_opcode());
EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[1]->arch_opcode());
EXPECT_EQ(kMode_None, s[1]->addressing_mode());
- EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[1]->opcode()),
+ EXPECT_EQ(RecordWriteModeField::decode(s[1]->opcode()),
RecordWriteMode::kValueIsAny);
}
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ OpIndex high = m.Projection(res, 1);
+ m.Return(m.Word64Add(low, high));
+ Stream s = m.Build();
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kMips64Add64_3, s[0]->arch_opcode());
+ EXPECT_EQ(kMips64Dadd, s[1]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(2U, s[0]->OutputCount());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, Word64Add3UnusedHigh) {
+ StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint64(),
+ MachineType::Uint64(), MachineType::Uint64());
+ V<Word64> p0 = m.Parameter<Word64>(0);
+ V<Word64> p1 = m.Parameter<Word64>(1);
+ V<Word64> p2 = m.Parameter<Word64>(2);
+ V<Word64Pair> res = m.Word64Add3(p0, p1, p2);
+ OpIndex low = m.Projection(res, 0);
+ m.Return(low);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kMips64Add64_3, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ ASSERT_EQ(1U, s[0]->OutputCount());
+}
+
} // namespace turboshaft
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/test/unittests/compiler/riscv64/turboshaft-instruction-selector-riscv64-unittest.cc b/deps/v8/test/unittests/compiler/riscv64/turboshaft-instruction-selector-riscv64-unittest.cc
index 39f0b82e219..12e3644a67b 100644
--- a/deps/v8/test/unittests/compiler/riscv64/turboshaft-instruction-selector-riscv64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/riscv64/turboshaft-instruction-selector-riscv64-unittest.cc
@@ -191,11 +191,12 @@ const IntCmp kUnsignedCmpInstructions[] = {
{{TSBinop::kWord64NotEqual, "Word64NotEqual", kRiscvCmp,
MachineType::Int64()},
1U},
- {{TSBinop::kWord32Equal, "Word32Equal", kRiscvCmp, MachineType::Int32()},
- 3},
- {{TSBinop::kWord32NotEqual, "Word32NotEqual", kRiscvCmp,
+ {{TSBinop::kWord32Equal, "Word32Equal", kRiscvCmp32Eq,
MachineType::Int32()},
- 3},
+ 1},
+ {{TSBinop::kWord32NotEqual, "Word32NotEqual", kRiscvCmp32Eq,
+ MachineType::Int32()},
+ 1},
{{TSBinop::kUint32LessThan, "Uint32LessThan", kRiscvCmp,
MachineType::Uint32()},
3},
@@ -349,47 +350,20 @@ TEST_P(TurboshaftInstructionSelectorUnsignedCmpTest, Parameter) {
StreamBuilder m(this, type, type, type);
m.Return(m.Emit(cmp.mi.op, m.Parameter(0), m.Parameter(1)));
Stream s = m.Build();
- if (v8_flags.debug_code &&
- type.representation() == MachineRepresentation::kWord32 &&
- cmp.expected_size == 1) {
- ASSERT_EQ(6U, s.size());
-
- EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+ ASSERT_EQ(cmp.expected_size, s.size());
+ if (cmp.expected_size == 3) {
+ // Non-equality 32-bit compares are normalized with two Shl64.
+ EXPECT_EQ(kRiscvShl64, s[0]->arch_opcode());
EXPECT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kRiscvShl64, s[1]->arch_opcode());
EXPECT_EQ(2U, s[1]->InputCount());
EXPECT_EQ(1U, s[1]->OutputCount());
-
- EXPECT_EQ(kRiscvShl64, s[2]->arch_opcode());
- EXPECT_EQ(2U, s[2]->InputCount());
- EXPECT_EQ(1U, s[2]->OutputCount());
-
- EXPECT_EQ(cmp.mi.arch_opcode, s[3]->arch_opcode());
- EXPECT_EQ(2U, s[3]->InputCount());
- EXPECT_EQ(1U, s[3]->OutputCount());
-
- EXPECT_EQ(kRiscvAssertEqual, s[4]->arch_opcode());
-
- EXPECT_EQ(cmp.mi.arch_opcode, s[5]->arch_opcode());
- EXPECT_EQ(2U, s[5]->InputCount());
- EXPECT_EQ(1U, s[5]->OutputCount());
- } else {
- ASSERT_EQ(cmp.expected_size, s.size());
- if (cmp.expected_size == 3) {
- EXPECT_EQ(kRiscvShl64, s[0]->arch_opcode());
- EXPECT_EQ(2U, s[0]->InputCount());
- EXPECT_EQ(1U, s[0]->OutputCount());
-
- EXPECT_EQ(kRiscvShl64, s[1]->arch_opcode());
- EXPECT_EQ(2U, s[1]->InputCount());
- EXPECT_EQ(1U, s[1]->OutputCount());
- }
- EXPECT_EQ(cmp.mi.arch_opcode, s[cmp.expected_size - 1]->arch_opcode());
- EXPECT_EQ(2U, s[0]->InputCount());
- EXPECT_EQ(1U, s[0]->OutputCount());
}
+ EXPECT_EQ(cmp.mi.arch_opcode, s[cmp.expected_size - 1]->arch_opcode());
+ EXPECT_EQ(2U, s[cmp.expected_size - 1]->InputCount());
+ EXPECT_EQ(1U, s[cmp.expected_size - 1]->OutputCount());
}
INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
@@ -690,16 +664,19 @@ TEST_F(TurboshaftInstructionSelectorTest, ChangesFromToSmi) {
}
}
-TEST_F(TurboshaftInstructionSelectorTest, ChangesFloat32ToUin64) {
+TEST_F(TurboshaftInstructionSelectorTest, ChangesFloat32ToUint64) {
{
StreamBuilder m(this, MachineType::Uint64(), MachineType::Float32());
m.Return(m.Emit(TSUnop::kChangeUint32ToUint64,
m.Emit(TSUnop::kBitcastFloat32ToWord32, m.Parameter(0))));
Stream s = m.Build();
- ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kRiscvBitcastDL, s[0]->arch_opcode());
- ASSERT_EQ(1U, s[0]->InputCount());
- EXPECT_EQ(1U, s[0]->OutputCount());
+ // The bitcast is materialized with fmv.x.w (sign-extending), then
+ // zext.w zero-extends, as required by ChangeUint32ToUint64.
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kRiscvBitcastFloat32ToInt32, s[0]->arch_opcode());
+ EXPECT_EQ(kRiscvZeroExtendWord, s[1]->arch_opcode());
+ ASSERT_EQ(1U, s[1]->InputCount());
+ EXPECT_EQ(1U, s[1]->OutputCount());
}
}
@@ -1456,6 +1433,43 @@ TEST_F(TurboshaftInstructionSelectorTest, Word64EqualWithZero) {
}
}
+// Word32 equality/inequality is lowered to a single kRiscvCmp32Eq (subw +
+// zero test) instead of two Shl64 + kRiscvCmp.
+TEST_F(TurboshaftInstructionSelectorTest, Word32EqualUsesSub32) {
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ m.Return(m.Emit(TSBinop::kWord32Equal, m.Parameter(0), m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kRiscvCmp32Eq, s[0]->arch_opcode());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(kEqual, s[0]->flags_condition());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsUnallocated());
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ m.Return(m.Emit(TSBinop::kWord32NotEqual, m.Parameter(0), m.Parameter(1)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kRiscvCmp32Eq, s[0]->arch_opcode());
+ EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ }
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithConstantUsesSub32) {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ m.Return(m.Emit(TSBinop::kWord32Equal, m.Parameter(0), m.Int32Constant(42)));
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kRiscvCmp32Eq, s[0]->arch_opcode());
+ ASSERT_EQ(2U, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
// TEST_F(TurboshaftInstructionSelectorTest, Word32Clz) {
// StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32());
// auto p0 = m.Parameter(0);
@@ -1829,7 +1843,7 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
Stream s = m.Build();
ASSERT_EQ(1u, s.size());
- EXPECT_EQ(kRiscvCmp32, s[0]->arch_opcode());
+ EXPECT_EQ(kRiscvCmp32Eq, s[0]->arch_opcode());
ASSERT_EQ(2u, s[0]->InputCount());
EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
}
diff --git a/deps/v8/test/unittests/compiler/turboshaft/instruction-selection-normalization-reducer-unittest.cc b/deps/v8/test/unittests/compiler/turboshaft/instruction-selection-normalization-reducer-unittest.cc
new file mode 100644
index 00000000000..bfc06da08b3
--- /dev/null
+++ b/deps/v8/test/unittests/compiler/turboshaft/instruction-selection-normalization-reducer-unittest.cc
@@ -0,0 +1,67 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/turboshaft/instruction-selection-normalization-reducer.h"
+
+#include <array>
+
+#include "test/unittests/compiler/turboshaft/reducer-test.h"
+
+namespace v8::internal::compiler::turboshaft {
+
+using InstructionSelectionNormalizationReducerTest = ReducerTest;
+
+#if V8_ENABLE_WEBASSEMBLY && defined(V8_TARGET_ARCH_ARM64)
+TEST_F(InstructionSelectionNormalizationReducerTest,
+ ReduceWideningLoadTransforms) {
+ using TransformKind = Simd128LoadTransformOp::TransformKind;
+ using UnaryKind = Simd128UnaryOp::Kind;
+ struct TestCase {
+ TransformKind transform_kind;
+ UnaryKind extension_kind;
+ };
+ constexpr std::array test_cases = {
+ TestCase{TransformKind::k8x8S, UnaryKind::kI16x8SConvertI8x16Low},
+ TestCase{TransformKind::k8x8U, UnaryKind::kI16x8UConvertI8x16Low},
+ TestCase{TransformKind::k16x4S, UnaryKind::kI32x4SConvertI16x8Low},
+ TestCase{TransformKind::k16x4U, UnaryKind::kI32x4UConvertI16x8Low},
+ TestCase{TransformKind::k32x2S, UnaryKind::kI64x2SConvertI32x4Low},
+ TestCase{TransformKind::k32x2U, UnaryKind::kI64x2UConvertI32x4Low},
+ };
+ const std::array parameter_reps = {RegisterRepresentation::WordPtr(),
+ RegisterRepresentation::WordPtr()};
+
+ for (const TestCase& test_case : test_cases) {
+ auto test = CreateFromGraph(
+ base::VectorOf(parameter_reps),
+ [test_case](TestInstance& t) {
+ V<WordPtr> base = t.GetParameter<WordPtr>(0);
+ V<WordPtr> index = t.GetParameter<WordPtr>(1);
+ V<Simd128> load = t.Capture(t.Asm().Simd128LoadTransform(
+ base, index, LoadOp::Kind::Trapping(),
+ test_case.transform_kind, 8),
+ "load");
+ t.Asm().Return(load);
+ },
+ true);
+
+ test.Run<InstructionSelectionNormalizationReducer>();
+
+ const auto& reduction = test.GetCapture("load");
+ const Simd128LoadTransformOp* load =
+ reduction.GetFirst<Simd128LoadTransformOp>();
+ const Simd128UnaryOp* extension = reduction.GetFirst<Simd128UnaryOp>();
+
+ ASSERT_NE(load, nullptr);
+ EXPECT_EQ(TransformKind::k64Zero, load->transform_kind);
+ EXPECT_EQ(LoadOp::Kind::Trapping(), load->load_kind);
+ EXPECT_EQ(8, load->offset);
+ ASSERT_NE(extension, nullptr);
+ EXPECT_EQ(test_case.extension_kind, extension->kind);
+ EXPECT_EQ(test.graph().Index(*load), extension->input());
+ }
+}
+#endif // V8_ENABLE_WEBASSEMBLY && V8_TARGET_ARCH_ARM64
+
+} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/turboshaft/wasm-shuffle-reducer-unittest.cc b/deps/v8/test/unittests/compiler/turboshaft/wasm-shuffle-reducer-unittest.cc
index 18782ae8173..09e46cf73ab 100644
--- a/deps/v8/test/unittests/compiler/turboshaft/wasm-shuffle-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/turboshaft/wasm-shuffle-reducer-unittest.cc
@@ -12,7 +12,7 @@
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/required-optimization-reducer.h"
-#include "test/common/flag-utils.h"
+#include "test/common/wasm/flag-utils.h"
#include "test/unittests/compiler/turboshaft/reducer-test.h"
namespace v8::internal::compiler::turboshaft {
@@ -228,6 +228,152 @@ TEST_F(ReducerTest, BinaryExtLowShuffle) {
}
}
+TEST_F(ReducerTest, BinaryPassThruShuffleWidensToLaneBoundary) {
+ FLAG_SCOPE(future_wasm_simd_opt);
+ auto test = CreateFromGraph(1, [&](auto& Asm) {
+ auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ auto zero =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+ auto one =
+ __ Simd128Splat(__ Word32Constant(1), Simd128SplatOp::Kind::kI32x4);
+ auto two =
+ __ Simd128Splat(__ Word32Constant(2), Simd128SplatOp::Kind::kI32x4);
+ auto three =
+ __ Simd128Splat(__ Word32Constant(3), Simd128SplatOp::Kind::kI32x4);
+ auto four =
+ __ Simd128Splat(__ Word32Constant(4), Simd128SplatOp::Kind::kI32x4);
+ auto five =
+ __ Simd128Splat(__ Word32Constant(5), Simd128SplatOp::Kind::kI32x4);
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+ V<Simd128> unary_shuffle =
+ Asm.Capture(__ Simd128Shuffle(zero, one, ShuffleKind, shuffle_bytes),
+ "unary_shuffle");
+ V<Simd128> binary_left_shuffle =
+ Asm.Capture(__ Simd128Shuffle(one, two, ShuffleKind, shuffle_bytes),
+ "binary_left_shuffle");
+ V<Simd128> binary_right_shuffle =
+ Asm.Capture(__ Simd128Shuffle(two, three, ShuffleKind, shuffle_bytes),
+ "binary_right_shuffle");
+ V<Simd128> ternary_first_shuffle =
+ Asm.Capture(__ Simd128Shuffle(three, four, ShuffleKind, shuffle_bytes),
+ "ternary_first_shuffle");
+ V<Simd128> ternary_second_shuffle =
+ Asm.Capture(__ Simd128Shuffle(four, five, ShuffleKind, shuffle_bytes),
+ "ternary_second_shuffle");
+ V<Simd128> ternary_third_shuffle =
+ Asm.Capture(__ Simd128Shuffle(five, zero, ShuffleKind, shuffle_bytes),
+ "ternary_third_shuffle");
+
+ OpIndex unary =
+ __ Simd128Unary(unary_shuffle, Simd128UnaryOp::Kind::kI8x16Abs);
+ OpIndex binary = __ Simd128Binop(binary_left_shuffle, binary_right_shuffle,
+ Simd128BinopOp::Kind::kI16x8Add);
+ OpIndex ternary = __ Simd128Ternary(
+ ternary_first_shuffle, ternary_second_shuffle, ternary_third_shuffle,
+ Simd128TernaryOp::Kind::kI64x2RelaxedLaneSelect);
+
+ OpIndex unary_binary =
+ __ Simd128Binop(unary, binary, Simd128BinopOp::Kind::kS128Or);
+ OpIndex result =
+ __ Simd128Binop(unary_binary, ternary, Simd128BinopOp::Kind::kS128Or);
+ __ Return(
+ __ Simd128ExtractLane(result, Simd128ExtractLaneOp::Kind::kI8x16S, 0));
+ });
+
+ WasmShuffleAnalyzer analyzer(test.zone(), test.graph());
+ analyzer.Run();
+ EXPECT_TRUE(analyzer.ShouldReduce());
+ EXPECT_TRUE(analyzer.GetDemandedBytes(test.GetCapture("unary_shuffle").Get())
+ .IsLow(1));
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("binary_left_shuffle").Get())
+ .IsLow(2));
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("binary_right_shuffle").Get())
+ .IsLow(2));
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("ternary_first_shuffle").Get())
+ .IsLow(8));
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("ternary_second_shuffle").Get())
+ .IsLow(8));
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("ternary_third_shuffle").Get())
+ .IsLow(8));
+ test.Run<WasmShuffleReducer>();
+}
+
+TEST_F(ReducerTest, PassThruDepthLimit) {
+ FLAG_SCOPE(future_wasm_simd_opt);
+ constexpr uint8_t kLimit = DemandedByteAnalysis::kMaxPassThruDepth;
+ auto test_depth = std::to_array<uint8_t>({kLimit, kLimit + 1});
+
+ for (uint8_t depth : test_depth) {
+ SCOPED_TRACE(static_cast<int>(depth));
+ auto test = CreateFromGraph(1, [depth](auto& Asm) {
+ auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ auto left =
+ __ Simd128Splat(__ Word32Constant(1), Simd128SplatOp::Kind::kI32x4);
+ auto right =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+ OpIndex shuffle = Asm.Capture(
+ __ Simd128Shuffle(left, right, ShuffleKind, shuffle_bytes),
+ "shuffle");
+ OpIndex value = shuffle;
+ for (uint8_t i = 0; i < depth; ++i) {
+ value = __ Simd128Unary(value, Simd128UnaryOp::Kind::kS128Not);
+ }
+ __ Return(
+ __ Simd128ExtractLane(value, Simd128ExtractLaneOp::Kind::kI8x16S, 0));
+ });
+
+ WasmShuffleAnalyzer analyzer(test.zone(), test.graph());
+ analyzer.Run();
+ if (depth <= kLimit) {
+ EXPECT_TRUE(analyzer.ShouldReduce());
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("shuffle").Get()).IsLow(1));
+ } else {
+ EXPECT_FALSE(analyzer.ShouldReduce());
+ }
+ test.Run<WasmShuffleReducer>();
+ }
+}
+
+TEST_F(ReducerTest, LowHalfOpsDoNotConsumePassThruDepth) {
+ FLAG_SCOPE(future_wasm_simd_opt);
+ constexpr uint8_t kLimit = DemandedByteAnalysis::kMaxPassThruDepth;
+
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ auto left =
+ __ Simd128Splat(__ Word32Constant(1), Simd128SplatOp::Kind::kI32x4);
+ auto right =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+ OpIndex shuffle = Asm.Capture(
+ __ Simd128Shuffle(left, right, ShuffleKind, shuffle_bytes), "shuffle");
+ OpIndex value = shuffle;
+ for (uint8_t i = 0; i < kLimit; ++i) {
+ value = __ Simd128Unary(value, Simd128UnaryOp::Kind::kS128Not);
+ }
+ __ Return(
+ __ Simd128Unary(value, Simd128UnaryOp::Kind::kI16x8SConvertI8x16Low));
+ });
+
+ WasmShuffleAnalyzer analyzer(test.zone(), test.graph());
+ analyzer.Run();
+ EXPECT_TRUE(analyzer.ShouldReduce());
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(test.GetCapture("shuffle").Get()).IsLow(8));
+ test.Run<WasmShuffleReducer>();
+}
+
TEST_F(ReducerTest, BinaryExtLowUnaryShuffle) {
// Expected reduced shuffle lengths when used solely by the given op.
std::array<std::tuple<Simd128BinopOp::Kind, Simd128UnaryOp::Kind, uint8_t>,
@@ -979,11 +1125,15 @@ TEST_F(ReducerTest, ShuffleShuffle) {
});
WasmShuffleAnalyzer analyzer(test.zone(), test.graph());
analyzer.Run();
- EXPECT_TRUE(analyzer.ShouldReduce());
- const Simd128ShuffleOp* input_shuffle =
- test.GetCapture("input_shuffle").GetAs<Simd128ShuffleOp>();
- EXPECT_TRUE(
- analyzer.GetDemandedBytes(input_shuffle).IsLow(demanded.bytes()));
+ if (demanded.bytes() != 16) {
+ EXPECT_TRUE(analyzer.ShouldReduce());
+ const Simd128ShuffleOp* input_shuffle =
+ test.GetCapture("input_shuffle").GetAs<Simd128ShuffleOp>();
+ EXPECT_TRUE(
+ analyzer.GetDemandedBytes(input_shuffle).IsLow(demanded.bytes()));
+ } else {
+ EXPECT_FALSE(analyzer.ShouldReduce());
+ }
test.Run<WasmShuffleReducer>();
}
}
diff --git a/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc b/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc
index c6e3dd24e27..6fc0fff3105 100644
--- a/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc
+++ b/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc
@@ -325,9 +325,9 @@ TEST_F(WasmSimdTest, Simd256Extract128Lane_ConstantFolding) {
24, 25, 26, 27, 28, 29, 30, 31};
const uint8_t* actual_low =
- test.GetCapture("low").GetAs<Simd128ConstantOp>()->value;
+ test.GetCapture("low").GetAs<Simd128ConstantOp>()->value.data();
const uint8_t* actual_high =
- test.GetCapture("high").GetAs<Simd128ConstantOp>()->value;
+ test.GetCapture("high").GetAs<Simd128ConstantOp>()->value.data();
for (int i = 0; i < kSimd128Size; i++) {
ASSERT_EQ(expected_low[i], actual_low[i]);
diff --git a/deps/v8/test/unittests/compiler/x64/turboshaft-instruction-selector-x64-unittest.cc b/deps/v8/test/unittests/compiler/x64/turboshaft-instruction-selector-x64-unittest.cc
index 8560d6f2b74..40f43ba878b 100644
--- a/deps/v8/test/unittests/compiler/x64/turboshaft-instruction-selector-x64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/x64/turboshaft-instruction-selector-x64-unittest.cc
@@ -3147,7 +3147,7 @@ TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[0]->arch_opcode());
EXPECT_EQ(AtomicMemoryOrderField::decode(s[0]->opcode()),
AtomicMemoryOrder::kSeqCst);
- EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[0]->opcode()),
+ EXPECT_EQ(RecordWriteModeField::decode(s[0]->opcode()),
RecordWriteMode::kValueIsAny);
}
diff --git a/deps/v8/test/unittests/debug/debug-block-list-unittest.cc b/deps/v8/test/unittests/debug/debug-block-list-unittest.cc
new file mode 100644
index 00000000000..59bc6b7394d
--- /dev/null
+++ b/deps/v8/test/unittests/debug/debug-block-list-unittest.cc
@@ -0,0 +1,317 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/debug/debug-block-list.h"
+
+#include "include/v8-function.h"
+#include "src/api/api-inl.h"
+#include "src/debug/debug-scope-info.h"
+#include "src/execution/isolate-inl.h"
+#include "src/objects/js-function-inl.h"
+#include "src/objects/scope-info-inl.h"
+#include "src/objects/script-inl.h"
+#include "src/objects/shared-function-info-inl.h"
+#include "src/objects/string-set-inl.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+class DebugBlockListTest : public TestWithNativeContext {
+ public:
+ DirectHandle<SharedFunctionInfo> GetSharedFunctionInfo(const char* name) {
+ DirectHandle<Object> val = RunJS(name);
+ DirectHandle<JSFunction> func = Cast<JSFunction>(val);
+ return direct_handle(func->shared(), isolate());
+ }
+
+ bool HasInBlockList(DirectHandle<StringSet> blocklist, const char* name) {
+ DirectHandle<String> str =
+ isolate()->factory()->InternalizeUtf8String(name);
+ return blocklist->Has(isolate(), str);
+ }
+};
+
+TEST_F(DebugBlockListTest, TopLevelFunctionCollectsOwnStackLocals) {
+ RunJS(R"(
+ function f(a) {
+ let local = 1;
+ return a + local;
+ }
+ function empty() {}
+ var arrow = () => {};
+ )");
+
+ DirectHandle<SharedFunctionInfo> sfi = GetSharedFunctionInfo("f");
+ Handle<StringSet> blocklist = EnsureLocalsBlockList(isolate(), sfi);
+ EXPECT_EQ(blocklist->NumberOfElements(), 3u);
+ EXPECT_TRUE(HasInBlockList(blocklist, "a"));
+ EXPECT_TRUE(HasInBlockList(blocklist, "local"));
+ EXPECT_TRUE(HasInBlockList(blocklist, "this"));
+
+ DirectHandle<SharedFunctionInfo> empty_sfi = GetSharedFunctionInfo("empty");
+ Handle<StringSet> empty_bl = EnsureLocalsBlockList(isolate(), empty_sfi);
+ EXPECT_EQ(empty_bl->NumberOfElements(), 1u);
+ EXPECT_TRUE(HasInBlockList(empty_bl, "this"));
+
+ DirectHandle<SharedFunctionInfo> arrow_sfi = GetSharedFunctionInfo("arrow");
+ Handle<StringSet> arrow_bl = EnsureLocalsBlockList(isolate(), arrow_sfi);
+ EXPECT_EQ(arrow_bl->NumberOfElements(), 0u);
+ EXPECT_FALSE(HasInBlockList(arrow_bl, "this"));
+}
+
+TEST_F(DebugBlockListTest, CollectsStackAllocatedLocalsAndParametersFromOuter) {
+ RunJS(R"(
+ function outer(param_stack, param_ctx) {
+ let stack_let = 1;
+ var stack_var = 2;
+ let ctx_let = 3;
+ return function inner(inner_stack) {
+ return param_ctx + ctx_let + inner_stack;
+ };
+ }
+ var inner_fn = outer(10, 20);
+ )");
+
+ DirectHandle<SharedFunctionInfo> inner_sfi =
+ GetSharedFunctionInfo("inner_fn");
+ Handle<StringSet> inner_bl = EnsureLocalsBlockList(isolate(), inner_sfi);
+ EXPECT_TRUE(HasInBlockList(inner_bl, "inner_stack"));
+ EXPECT_FALSE(HasInBlockList(inner_bl, "param_stack"));
+
+ DirectHandle<ScopeInfo> outer_scope_info(
+ inner_sfi->scope_info()->OuterScopeInfo(), isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_outer_bl =
+ isolate()->LocalsBlockListCacheGet(outer_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_outer_bl));
+ DirectHandle<StringSet> outer_bl(Cast<StringSet>(maybe_outer_bl), isolate());
+
+ // Stack-allocated outer variables and parameters must be in outer's
+ // blocklist.
+ EXPECT_TRUE(HasInBlockList(outer_bl, "param_stack"));
+ EXPECT_TRUE(HasInBlockList(outer_bl, "stack_let"));
+ EXPECT_TRUE(HasInBlockList(outer_bl, "stack_var"));
+
+ // Context-allocated outer variables and parameters must not be in the
+ // blocklist.
+ EXPECT_FALSE(HasInBlockList(outer_bl, "param_ctx"));
+ EXPECT_FALSE(HasInBlockList(outer_bl, "ctx_let"));
+}
+
+TEST_F(DebugBlockListTest, SplitsBlockListsAcrossMultipleContextBoundaries) {
+ RunJS(R"(
+ function grandOuter(go_stack, go_ctx) {
+ let go_local = 1;
+ return function middle(mid_stack, mid_ctx) {
+ let mid_local = 2;
+ {
+ let block_stack = 3;
+ let block_ctx = 4;
+ return function inner(in_stack) {
+ return go_ctx + mid_ctx + block_ctx + in_stack;
+ };
+ }
+ };
+ }
+ var inner_fn = grandOuter(1, 2)(3, 4);
+ )");
+
+ DirectHandle<SharedFunctionInfo> inner_sfi =
+ GetSharedFunctionInfo("inner_fn");
+ Handle<StringSet> inner_blocklist =
+ EnsureLocalsBlockList(isolate(), inner_sfi);
+
+ // 1. `inner`'s blocklist covers [inner, block) -> `in_stack`.
+ EXPECT_TRUE(HasInBlockList(inner_blocklist, "in_stack"));
+ EXPECT_FALSE(HasInBlockList(inner_blocklist, "block_stack"));
+ EXPECT_FALSE(HasInBlockList(inner_blocklist, "block_ctx"));
+
+ // 2. `block`'s ScopeInfo is `inner->scope_info()->OuterScopeInfo()`.
+ // Its blocklist covers [block, middle) -> `block_stack`.
+ DirectHandle<ScopeInfo> block_scope_info(
+ inner_sfi->scope_info()->OuterScopeInfo(), isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_block_bl =
+ isolate()->LocalsBlockListCacheGet(block_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_block_bl));
+ DirectHandle<StringSet> block_bl(Cast<StringSet>(maybe_block_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(block_bl, "block_stack"));
+ EXPECT_FALSE(HasInBlockList(block_bl, "block_ctx"));
+ EXPECT_FALSE(HasInBlockList(block_bl, "mid_stack"));
+
+ // 3. `middle`'s ScopeInfo is `block_scope_info->OuterScopeInfo()`.
+ // Its blocklist covers [middle, grandOuter) -> `mid_stack` and `mid_local`.
+ DirectHandle<ScopeInfo> mid_scope_info(block_scope_info->OuterScopeInfo(),
+ isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_mid_bl =
+ isolate()->LocalsBlockListCacheGet(mid_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_mid_bl));
+ DirectHandle<StringSet> mid_bl(Cast<StringSet>(maybe_mid_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(mid_bl, "mid_stack"));
+ EXPECT_TRUE(HasInBlockList(mid_bl, "mid_local"));
+ EXPECT_FALSE(HasInBlockList(mid_bl, "mid_ctx"));
+ EXPECT_FALSE(HasInBlockList(mid_bl, "go_stack"));
+
+ // 4. `grandOuter`'s ScopeInfo is `mid_scope_info->OuterScopeInfo()`.
+ // Its blocklist covers [grandOuter, script) -> `go_stack` and `go_local`.
+ DirectHandle<ScopeInfo> go_scope_info(mid_scope_info->OuterScopeInfo(),
+ isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_go_bl =
+ isolate()->LocalsBlockListCacheGet(go_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_go_bl));
+ DirectHandle<StringSet> go_bl(Cast<StringSet>(maybe_go_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(go_bl, "go_stack"));
+ EXPECT_TRUE(HasInBlockList(go_bl, "go_local"));
+ EXPECT_FALSE(HasInBlockList(go_bl, "go_ctx"));
+}
+
+TEST_F(DebugBlockListTest, AccumulatesThroughNonContextAllocatingScopes) {
+ RunJS(R"(
+ function outer(outer_ctx) {
+ let outer_stack = 1;
+ function middleNoContext(mid_stack) {
+ let mid_local = 2;
+ {
+ let block_stack = 3;
+ return function inner(in_stack) {
+ return outer_ctx + in_stack;
+ };
+ }
+ }
+ return middleNoContext(10);
+ }
+ var inner_fn = outer(42);
+ )");
+
+ DirectHandle<SharedFunctionInfo> inner_sfi =
+ GetSharedFunctionInfo("inner_fn");
+ Handle<StringSet> inner_blocklist =
+ EnsureLocalsBlockList(isolate(), inner_sfi);
+
+ // Neither `block` nor `middleNoContext` allocates a context, so `inner`'s
+ // blocklist [inner, outer) accumulates stack variables from `inner`,
+ // `block`, and `middleNoContext`.
+ EXPECT_TRUE(HasInBlockList(inner_blocklist, "in_stack"));
+ EXPECT_TRUE(HasInBlockList(inner_blocklist, "block_stack"));
+ EXPECT_TRUE(HasInBlockList(inner_blocklist, "mid_stack"));
+ EXPECT_TRUE(HasInBlockList(inner_blocklist, "mid_local"));
+ EXPECT_FALSE(HasInBlockList(inner_blocklist, "outer_stack"));
+ EXPECT_FALSE(HasInBlockList(inner_blocklist, "outer_ctx"));
+
+ // `outer`'s blocklist [outer, script) contains `outer_stack`.
+ DirectHandle<ScopeInfo> outer_scope_info(
+ inner_sfi->scope_info()->OuterScopeInfo(), isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_outer_bl =
+ isolate()->LocalsBlockListCacheGet(outer_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_outer_bl));
+ DirectHandle<StringSet> outer_bl(Cast<StringSet>(maybe_outer_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(outer_bl, "outer_stack"));
+ EXPECT_FALSE(HasInBlockList(outer_bl, "outer_ctx"));
+}
+
+TEST_F(DebugBlockListTest, CachesResultOnSubsequentCalls) {
+ RunJS(R"(
+ function outer(a) {
+ let b = 1;
+ return function inner() { return a; };
+ }
+ var inner_fn = outer(1);
+ )");
+
+ DirectHandle<SharedFunctionInfo> inner_sfi =
+ GetSharedFunctionInfo("inner_fn");
+ Handle<StringSet> first = EnsureLocalsBlockList(isolate(), inner_sfi);
+ Handle<StringSet> second = EnsureLocalsBlockList(isolate(), inner_sfi);
+ EXPECT_EQ(*first, *second);
+}
+
+TEST_F(DebugBlockListTest, SiblingInnerBlockNotIncludedInBlockLists) {
+ RunJS(R"(
+ function f() {
+ let a = 42;
+ let b = 21;
+ () => b;
+ {
+ const c = 'foo';
+ }
+ return function g() {};
+ }
+ var g_fn = f();
+ )");
+
+ DirectHandle<SharedFunctionInfo> g_sfi = GetSharedFunctionInfo("g_fn");
+ Handle<StringSet> g_bl = EnsureLocalsBlockList(isolate(), g_sfi);
+ EXPECT_FALSE(HasInBlockList(g_bl, "a"));
+ EXPECT_FALSE(HasInBlockList(g_bl, "b"));
+ EXPECT_FALSE(HasInBlockList(g_bl, "c"));
+
+ DirectHandle<ScopeInfo> f_scope_info(g_sfi->scope_info()->OuterScopeInfo(),
+ isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_f_bl =
+ isolate()->LocalsBlockListCacheGet(f_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_f_bl));
+ DirectHandle<StringSet> f_bl(Cast<StringSet>(maybe_f_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(f_bl, "a"));
+ EXPECT_FALSE(HasInBlockList(f_bl, "b"));
+ EXPECT_FALSE(HasInBlockList(f_bl, "c"));
+}
+
+TEST_F(
+ DebugBlockListTest,
+ EnclosingInnerBlockSeparatedFromOuterFunctionAndCalculateScopeBlockList) {
+ RunJS(R"(
+ function f() {
+ let a = 42;
+ let b = 21;
+ () => b;
+ {
+ const c = 'foo';
+ return function g() {};
+ }
+ }
+ var g_fn = f();
+ )");
+
+ DirectHandle<SharedFunctionInfo> g_sfi = GetSharedFunctionInfo("g_fn");
+ Handle<StringSet> g_bl = EnsureLocalsBlockList(isolate(), g_sfi);
+
+ // `g`'s blocklist [g, f) contains `c` from the enclosing inner block,
+ // but not `a` or `b` from `f`.
+ EXPECT_TRUE(HasInBlockList(g_bl, "c"));
+ EXPECT_FALSE(HasInBlockList(g_bl, "a"));
+ EXPECT_FALSE(HasInBlockList(g_bl, "b"));
+
+ // `f`'s blocklist [f, script) contains `a`, and must NOT contain `c` from
+ // the inner block.
+ DirectHandle<ScopeInfo> f_scope_info(g_sfi->scope_info()->OuterScopeInfo(),
+ isolate());
+ Tagged<UnionOf<TheHole, StringSet>> maybe_f_bl =
+ isolate()->LocalsBlockListCacheGet(f_scope_info);
+ ASSERT_TRUE(IsStringSet(maybe_f_bl));
+ DirectHandle<StringSet> f_bl(Cast<StringSet>(maybe_f_bl), isolate());
+ EXPECT_TRUE(HasInBlockList(f_bl, "a"));
+ EXPECT_FALSE(HasInBlockList(f_bl, "b"));
+ EXPECT_FALSE(HasInBlockList(f_bl, "c"));
+
+ // Verify `CalculateScopeBlockList` on the inner block scope directly.
+ DirectHandle<Script> script(Cast<Script>(g_sfi->script()), isolate());
+ Handle<DebugScriptScopeInfo> debug_scope_info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ std::optional<DebugScriptScope> g_scope =
+ FindClosureScope(debug_scope_info, g_sfi->StartPosition(),
+ g_sfi->EndPosition(), FUNCTION_SCOPE);
+ ASSERT_TRUE(g_scope.has_value());
+ std::optional<DebugScriptScope> inner_block_scope = g_scope->parent();
+ ASSERT_TRUE(inner_block_scope.has_value());
+ EXPECT_FALSE(inner_block_scope->needs_context());
+
+ Handle<StringSet> block_bl =
+ CalculateScopeBlockList(isolate(), *inner_block_scope);
+ EXPECT_TRUE(HasInBlockList(block_bl, "c"));
+ EXPECT_FALSE(HasInBlockList(block_bl, "a"));
+ EXPECT_FALSE(HasInBlockList(block_bl, "b"));
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc b/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc
index c8d3b10a17a..eaced1b679f 100644
--- a/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc
+++ b/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc
@@ -5,6 +5,9 @@
#include "src/debug/debug-scope-info.h"
#include <iterator>
+#include <optional>
+#include <string>
+#include <vector>
#include "include/v8-function.h"
#include "src/api/api-inl.h"
@@ -452,6 +455,74 @@ TEST_F(DebugScopeInfoTest, ComplexScopeTypes) {
VerifyScopeTreeParity(parsed.script_scope(), script);
}
+// ParserBase::NewVarblockScope() creates a DeclarationScope with BLOCK_SCOPE
+// type for a function body with non-simple parameters, so is_declaration_scope
+// cannot be derived from the scope type. The body has to declare something,
+// otherwise Scope::FinalizeBlockScope() drops the scope again.
+TEST_F(DebugScopeInfoTest, VarblockScopeIsDeclarationScope) {
+ HandleScope scope(isolate());
+ ParsedScript parsed =
+ ParseAndSerialize("function f(a = 1) { let x = 2; return a + x; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ ASSERT_TRUE(func->is_function_scope());
+
+ auto varblock = func->first_child();
+ ASSERT_TRUE(varblock.has_value());
+ EXPECT_EQ(varblock->scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(varblock->is_block_scope());
+ EXPECT_TRUE(varblock->is_declaration_scope());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// The other NewVarblockScope() call site: class static initializer blocks.
+TEST_F(DebugScopeInfoTest, ClassStaticBlockIsDeclarationScope) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("class C { static { let x = 1; } }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ bool found_declaration_block_scope = false;
+ auto walk = [&](auto& self, const DebugScriptScope& current) -> void {
+ if (current.scope_type() == ScopeType::BLOCK_SCOPE &&
+ current.is_declaration_scope()) {
+ found_declaration_block_scope = true;
+ }
+ for (auto child = current.first_child(); child.has_value();
+ child = child->next_sibling()) {
+ self(self, *child);
+ }
+ };
+ walk(walk, script);
+ EXPECT_TRUE(found_declaration_block_scope);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// A varblock scope can also survive FinalizeBlockScope() without declaring
+// anything, via sloppy_eval_can_extend_vars().
+TEST_F(DebugScopeInfoTest, VarblockScopeWithSloppyEval) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("function f(a = 1) { eval(''); }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+
+ auto varblock = func->first_child();
+ ASSERT_TRUE(varblock.has_value());
+ EXPECT_EQ(varblock->scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(varblock->is_declaration_scope());
+ EXPECT_TRUE(varblock->sloppy_eval_can_extend_vars());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
TEST_F(DebugScopeInfoTest, NeedsContextAndUniqueId) {
HandleScope scope(isolate());
ParsedScript parsed = ParseAndSerialize(
@@ -798,6 +869,148 @@ TEST_F(DebugScopeInfoTest, SyntheticAndReceiverVariables) {
EXPECT_TRUE(found_private_member);
}
+namespace {
+
+// Builds a source string by repeating `pattern` `count` times, substituting the
+// current index for each "%d".
+std::string Repeat(const char* pattern, int count) {
+ std::string result;
+ for (int i = 0; i < count; ++i) {
+ for (const char* p = pattern; *p != '\0'; ++p) {
+ if (p[0] == '%' && p[1] == 'd') {
+ result += std::to_string(i);
+ ++p;
+ } else {
+ result += *p;
+ }
+ }
+ }
+ return result;
+}
+
+// How many declarations each test generates. Chosen to be large enough that
+// the resulting indices and counts need the full 32-bit fields.
+constexpr int kManyContextVariables = 9000;
+constexpr int kManyParameters = 40000;
+constexpr int kManyLocals = 70000;
+
+} // namespace
+
+// A sloppy direct eval forces context allocation of every variable, and
+// DeclarationScope::AllocateLocals() allocates the function variable last, so
+// it ends up with the highest context slot index in the scope.
+TEST_F(DebugScopeInfoTest, FunctionVariableWithLargeContextIndex) {
+ HandleScope scope(isolate());
+ std::string source = "var g = (function foo() {\n";
+ source += Repeat(" var v%d = %d;\n", kManyContextVariables);
+ source += " eval(\"\");\n return foo;\n});";
+ ParsedScript parsed = ParseAndSerialize(source.c_str());
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ ASSERT_TRUE(func->has_function_variable());
+
+ auto [alloc_info, index] = func->function_variable_info();
+ EXPECT_EQ(alloc_info, VariableAllocationInfo::CONTEXT);
+ EXPECT_GT(index, kManyContextVariables);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// Same, for the 'arguments' variable, which is allocated after all parameters.
+TEST_F(DebugScopeInfoTest, ArgumentsWithLargeContextIndex) {
+ HandleScope scope(isolate());
+ std::string source = "function g(";
+ source += Repeat("q%d,", kManyContextVariables);
+ source += "qLast) { eval(\"\"); return arguments; }";
+ ParsedScript parsed = ParseAndSerialize(source.c_str());
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ ASSERT_TRUE(func->has_arguments());
+
+ auto [alloc_info, index] = func->arguments_info();
+ EXPECT_EQ(alloc_info, VariableAllocationInfo::CONTEXT);
+ EXPECT_GT(index, kManyContextVariables);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// Parameters are part of Scope::locals() and their index goes up to
+// Code::kMaxArguments - 1.
+TEST_F(DebugScopeInfoTest, VariableWithLargeParameterSlotIndex) {
+ HandleScope scope(isolate());
+ std::string source = "function f(";
+ source += Repeat("p%d,", kManyParameters);
+ source += "pLast) { return p0; }";
+ ParsedScript parsed = ParseAndSerialize(source.c_str());
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+
+ int max_index = -1;
+ for (int i = 0; i < func->variable_count(); ++i) {
+ DebugVariableInfo var = func->variable(i);
+ if (var.location == VariableLocation::PARAMETER) {
+ if (var.index > max_index) max_index = var.index;
+ }
+ }
+ EXPECT_GE(max_index, kManyParameters);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// A single scope can declare a very large number of locals.
+TEST_F(DebugScopeInfoTest, ScopeWithVeryManyVariables) {
+ HandleScope scope(isolate());
+ std::string source = "function h() {\n";
+ source += Repeat("var w%d;\n", kManyLocals);
+ source += "return w0;\n}";
+ ParsedScript parsed = ParseAndSerialize(source.c_str());
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ EXPECT_GE(func->variable_count(), kManyLocals);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+// Same declarations, but a sloppy direct eval forces all of them into the
+// context. The highest context slot index then lands beyond 2^16, which is
+// what requires slot_index to be wider than 16 bits. (In the test above the
+// locals are unused and stay unallocated at index -1.)
+TEST_F(DebugScopeInfoTest, ContextSlotIndexAboveUint16Max) {
+ HandleScope scope(isolate());
+ std::string source = "function h() {\n";
+ source += Repeat("var w%d;\n", kManyLocals);
+ source += "eval(\"\");\nreturn w0;\n}";
+ ParsedScript parsed = ParseAndSerialize(source.c_str());
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+
+ int max_index = -1;
+ for (int i = 0; i < func->variable_count(); ++i) {
+ DebugVariableInfo var = func->variable(i);
+ if (var.location == VariableLocation::CONTEXT) {
+ if (var.index > max_index) max_index = var.index;
+ }
+ }
+ EXPECT_GT(max_index, 0xFFFF);
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
TEST_F(DebugScopeInfoTest, DebugScriptScopeInfoSideTable) {
HandleScope scope(isolate());
ParsedScript parsed1 = ParseAndSerialize("let a = 1;");
@@ -1331,5 +1544,393 @@ TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_Module) {
EXPECT_EQ(*info, *cached_info);
}
+namespace {
+
+// Collects the AST scopes rooted at `scope` in the same DFS pre-order that
+// SerializeDebugScriptScopeInfo() uses, so that an index into the result
+// matches the scope index in the serialized DebugScriptScopeInfo.
+void CollectScopesInPreOrder(Scope* scope, std::vector<Scope*>* scopes) {
+ scopes->push_back(scope);
+ for (Scope* inner = scope->inner_scope(); inner != nullptr;
+ inner = inner->sibling()) {
+ CollectScopesInPreOrder(inner, scopes);
+ }
+}
+
+std::vector<Scope*> CollectScopesInPreOrder(Scope* scope) {
+ std::vector<Scope*> scopes;
+ CollectScopesInPreOrder(scope, &scopes);
+ return scopes;
+}
+
+std::optional<DebugScriptScope> FindFirstScopeOfType(
+ DirectHandle<DebugScriptScopeInfo> info, ScopeType type) {
+ for (int i = 0; i < DebugScriptScopeCount(*info); ++i) {
+ DebugScriptScope scope = DebugScriptScope::FromIndex(info, i);
+ if (scope.scope_type() == type) return scope;
+ }
+ return std::nullopt;
+}
+
+// Returns the source position of `needle` in `source`, so that tests can spell
+// out break positions as source snippets instead of magic numbers.
+int PositionOf(const char* source, const char* needle) {
+ std::string_view haystack(source);
+ size_t position = haystack.find(needle);
+ CHECK_NE(position, std::string_view::npos);
+ return static_cast<int>(position);
+}
+
+} // namespace
+
+TEST_F(DebugScopeInfoTest, ContainsPosition) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("function foo() { let a = 1; }");
+ DebugScriptScope foo = DebugScriptScope::FromIndex(parsed.scope_info, 1);
+ ASSERT_TRUE(foo.is_function_scope());
+
+ const int start = foo.start_position();
+ const int end = foo.end_position();
+
+ EXPECT_FALSE(foo.ContainsPosition(start - 1, /*is_closure_found=*/true));
+ EXPECT_FALSE(foo.ContainsPosition(start, /*is_closure_found=*/true));
+ EXPECT_TRUE(foo.ContainsPosition(start + 1, /*is_closure_found=*/true));
+ EXPECT_TRUE(foo.ContainsPosition(end - 1, /*is_closure_found=*/true));
+ EXPECT_FALSE(foo.ContainsPosition(end, /*is_closure_found=*/true));
+ EXPECT_FALSE(foo.ContainsPosition(end + 1, /*is_closure_found=*/true));
+
+ // As long as the closure scope hasn't been found the end position is
+ // inclusive, because nested arrow functions can share it.
+ EXPECT_TRUE(foo.ContainsPosition(end, /*is_closure_found=*/false));
+ EXPECT_FALSE(foo.ContainsPosition(end + 1, /*is_closure_found=*/false));
+}
+
+TEST_F(DebugScopeInfoTest, ContainsPositionClassScopeIncludesStart) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("class C { x = 1; }");
+ std::optional<DebugScriptScope> class_scope =
+ FindFirstScopeOfType(parsed.scope_info, ScopeType::CLASS_SCOPE);
+ ASSERT_TRUE(class_scope.has_value());
+
+ // The source position points at Token::kClass while the class context is
+ // already pushed, so the start position has to be part of the scope.
+ EXPECT_TRUE(class_scope->ContainsPosition(class_scope->start_position(),
+ /*is_closure_found=*/true));
+ EXPECT_FALSE(class_scope->ContainsPosition(class_scope->start_position() - 1,
+ /*is_closure_found=*/true));
+}
+
+TEST_F(DebugScopeInfoTest, ContainsPositionWithScopeIncludesStart) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("with ({}) { let a = 1; }");
+ std::optional<DebugScriptScope> with_scope =
+ FindFirstScopeOfType(parsed.scope_info, ScopeType::WITH_SCOPE);
+ ASSERT_TRUE(with_scope.has_value());
+
+ EXPECT_TRUE(with_scope->ContainsPosition(with_scope->start_position(),
+ /*is_closure_found=*/true));
+ EXPECT_FALSE(with_scope->ContainsPosition(with_scope->start_position() - 1,
+ /*is_closure_found=*/true));
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeForFunction) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("function foo() { let a = 1; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ std::vector<Scope*> ast_scopes =
+ CollectScopesInPreOrder(parsed.script_scope());
+ ASSERT_EQ(ast_scopes.size(), 2u);
+ Scope* foo = ast_scopes[1];
+ ASSERT_TRUE(foo->is_function_scope());
+
+ std::optional<DebugScriptScope> found = FindClosureScope(
+ info, foo->start_position(), foo->end_position(), foo->scope_type());
+ ASSERT_TRUE(found.has_value());
+ EXPECT_EQ(found->scope_index(), 1);
+ EXPECT_EQ(found->start_position(), foo->start_position());
+ EXPECT_EQ(found->end_position(), foo->end_position());
+ EXPECT_EQ(found->scope_type(), ScopeType::FUNCTION_SCOPE);
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeForScriptScope) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("let a = 1;");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+ DebugScriptScope root = DebugScriptScope::FromIndex(info, 0);
+
+ std::optional<DebugScriptScope> found =
+ FindClosureScope(info, root.start_position(), root.end_position(),
+ ScopeType::SCRIPT_SCOPE);
+ ASSERT_TRUE(found.has_value());
+ EXPECT_EQ(found->scope_index(), 0);
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeDistinguishesScopeTypes) {
+ HandleScope scope(isolate());
+ // A class declaration that spans the whole script gives the class scope the
+ // exact same positions as the script scope, so the scope type is the only
+ // thing that tells the two apart.
+ ParsedScript parsed = ParseAndSerialize("class C { x = 1; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script_scope = DebugScriptScope::FromIndex(info, 0);
+ DebugScriptScope class_scope = DebugScriptScope::FromIndex(info, 1);
+ ASSERT_TRUE(script_scope.is_script_scope());
+ ASSERT_TRUE(class_scope.is_class_scope());
+ ASSERT_EQ(script_scope.start_position(), class_scope.start_position());
+ ASSERT_EQ(script_scope.end_position(), class_scope.end_position());
+
+ std::optional<DebugScriptScope> found_script =
+ FindClosureScope(info, script_scope.start_position(),
+ script_scope.end_position(), ScopeType::SCRIPT_SCOPE);
+ ASSERT_TRUE(found_script.has_value());
+ EXPECT_EQ(found_script->scope_index(), 0);
+
+ std::optional<DebugScriptScope> found_class =
+ FindClosureScope(info, class_scope.start_position(),
+ class_scope.end_position(), ScopeType::CLASS_SCOPE);
+ ASSERT_TRUE(found_class.has_value());
+ EXPECT_EQ(found_class->scope_index(), 1);
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeNestedArrowFunctions) {
+ HandleScope scope(isolate());
+ // Both arrow functions end at the same position.
+ ParsedScript parsed = ParseAndSerialize("const f = a => b => a + b;");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ std::vector<Scope*> ast_scopes =
+ CollectScopesInPreOrder(parsed.script_scope());
+ ASSERT_EQ(ast_scopes.size(), 3u);
+ Scope* outer_arrow = ast_scopes[1];
+ Scope* inner_arrow = ast_scopes[2];
+ ASSERT_TRUE(outer_arrow->is_function_scope());
+ ASSERT_TRUE(inner_arrow->is_function_scope());
+ ASSERT_EQ(outer_arrow->end_position(), inner_arrow->end_position());
+ ASSERT_NE(outer_arrow->start_position(), inner_arrow->start_position());
+
+ std::optional<DebugScriptScope> found_outer =
+ FindClosureScope(info, outer_arrow->start_position(),
+ outer_arrow->end_position(), ScopeType::FUNCTION_SCOPE);
+ ASSERT_TRUE(found_outer.has_value());
+ EXPECT_EQ(found_outer->scope_index(), 1);
+
+ std::optional<DebugScriptScope> found_inner =
+ FindClosureScope(info, inner_arrow->start_position(),
+ inner_arrow->end_position(), ScopeType::FUNCTION_SCOPE);
+ ASSERT_TRUE(found_inner.has_value());
+ EXPECT_EQ(found_inner->scope_index(), 2);
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeNoMatch) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("function foo() { let a = 1; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ std::vector<Scope*> ast_scopes =
+ CollectScopesInPreOrder(parsed.script_scope());
+ Scope* foo = ast_scopes[1];
+
+ // Positions that don't belong to any scope.
+ EXPECT_FALSE(FindClosureScope(info, foo->start_position() + 1,
+ foo->end_position(), ScopeType::FUNCTION_SCOPE)
+ .has_value());
+ // Matching positions but the wrong scope type.
+ EXPECT_FALSE(FindClosureScope(info, foo->start_position(),
+ foo->end_position(), ScopeType::BLOCK_SCOPE)
+ .has_value());
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeMatchesSerializationOrder) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "function outer(a = 1) {"
+ " let x = 2;"
+ " class C { static { let y = 3; } m() { return a; } }"
+ " try { } catch (e) { with ({}) { let z = 4; } }"
+ " return () => x;"
+ "}");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ std::vector<Scope*> ast_scopes =
+ CollectScopesInPreOrder(parsed.script_scope());
+ ASSERT_EQ(static_cast<int>(ast_scopes.size()), DebugScriptScopeCount(*info));
+
+ for (size_t i = 0; i < ast_scopes.size(); ++i) {
+ Scope* ast_scope = ast_scopes[i];
+ std::optional<DebugScriptScope> found =
+ FindClosureScope(info, ast_scope->start_position(),
+ ast_scope->end_position(), ast_scope->scope_type());
+ ASSERT_TRUE(found.has_value()) << "no match for AST scope " << i;
+ // Scopes are not unique in (start, end, type), so the lookup returns the
+ // first match in serialization order.
+ EXPECT_LE(found->scope_index(), static_cast<int>(i));
+ EXPECT_EQ(found->start_position(), ast_scope->start_position());
+ EXPECT_EQ(found->end_position(), ast_scope->end_position());
+ EXPECT_EQ(found->scope_type(), ast_scope->scope_type());
+ }
+}
+
+TEST_F(DebugScopeInfoTest, FindClosureScopeForModuleScope) {
+ v8::HandleScope scope(v8_isolate());
+ v8::ScriptOrigin origin(NewString("module.js"), 0, 0, false, -1,
+ v8::Local<v8::Value>(), false, false,
+ true /* is_module */);
+ v8::ScriptCompiler::Source script_source(
+ NewString("let module_x = 42;\n"
+ "export function getX() { return module_x; }"),
+ origin);
+ v8::Local<v8::Module> module =
+ v8::ScriptCompiler::CompileModule(v8_isolate(), &script_source)
+ .ToLocalChecked();
+ DirectHandle<SharedFunctionInfo> sfi =
+ Utils::OpenHandle(*module->GetUnboundModuleScript());
+ DirectHandle<Script> script(Cast<Script>(sfi->script()), isolate());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root = DebugScriptScope::FromIndex(info, 0);
+ ASSERT_TRUE(root.is_module_scope());
+
+ std::optional<DebugScriptScope> found =
+ FindClosureScope(info, root.start_position(), root.end_position(),
+ ScopeType::MODULE_SCOPE);
+ ASSERT_TRUE(found.has_value());
+ EXPECT_EQ(found->scope_index(), 0);
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeNestedBlocks) {
+ HandleScope scope(isolate());
+ const char* source =
+ "function foo() { let a = 1; { let b = 2; { let c = 3; } } }";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope foo = DebugScriptScope::FromIndex(info, 1);
+ ASSERT_TRUE(foo.is_function_scope());
+
+ DebugScriptScope outer_block =
+ FindInnermostScope(foo, PositionOf(source, "let b") + 1);
+ EXPECT_EQ(outer_block.scope_index(), 2);
+ EXPECT_TRUE(outer_block.is_block_scope());
+
+ DebugScriptScope inner_block =
+ FindInnermostScope(foo, PositionOf(source, "let c") + 1);
+ EXPECT_EQ(inner_block.scope_index(), 3);
+ EXPECT_TRUE(inner_block.is_block_scope());
+
+ // Positions outside of any block resolve to the closure scope itself.
+ DebugScriptScope function_scope =
+ FindInnermostScope(foo, PositionOf(source, "let a") + 1);
+ EXPECT_EQ(function_scope.scope_index(), foo.scope_index());
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeStartsAtClosureScope) {
+ HandleScope scope(isolate());
+ // The block scope of `bar` is not a descendant of `foo`, so searching from
+ // `foo` for a position inside `bar` must not leave `foo`.
+ const char* source =
+ "function foo() { let a = 1; } function bar() { { let b = 2; } }";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script_scope = DebugScriptScope::FromIndex(info, 0);
+ DebugScriptScope foo =
+ FindInnermostScope(script_scope, PositionOf(source, "let a") + 1);
+ ASSERT_TRUE(foo.is_function_scope());
+
+ DebugScriptScope found =
+ FindInnermostScope(foo, PositionOf(source, "let b") + 1);
+ EXPECT_EQ(found.scope_index(), foo.scope_index());
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeCatchScope) {
+ HandleScope scope(isolate());
+ const char* source = "function foo() { try { } catch (e) { let a = 1; } }";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope foo = DebugScriptScope::FromIndex(info, 1);
+ ASSERT_TRUE(foo.is_function_scope());
+
+ DebugScriptScope found =
+ FindInnermostScope(foo, PositionOf(source, "let a") + 1);
+ // The catch scope holds `e` and has the catch body block scope as its child.
+ EXPECT_TRUE(found.is_block_scope() || found.is_catch_scope());
+ std::optional<DebugScriptScope> catch_scope =
+ FindFirstScopeOfType(info, ScopeType::CATCH_SCOPE);
+ ASSERT_TRUE(catch_scope.has_value());
+ EXPECT_GE(found.start_position(), catch_scope->start_position());
+ EXPECT_LE(found.end_position(), catch_scope->end_position());
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeWithScope) {
+ HandleScope scope(isolate());
+ const char* source = "function foo() { with ({}) { let a = 1; } }";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope foo = DebugScriptScope::FromIndex(info, 1);
+ std::optional<DebugScriptScope> with_scope =
+ FindFirstScopeOfType(info, ScopeType::WITH_SCOPE);
+ ASSERT_TRUE(with_scope.has_value());
+
+ // "with" scopes accept their start position, because the context can already
+ // be pushed while the source position still points at the header.
+ DebugScriptScope found =
+ FindInnermostScope(foo, with_scope->start_position());
+ EXPECT_EQ(found.scope_index(), with_scope->scope_index());
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeClassScope) {
+ HandleScope scope(isolate());
+ const char* source = "function foo() { class C { m() {} } }";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope foo = DebugScriptScope::FromIndex(info, 1);
+ std::optional<DebugScriptScope> class_scope =
+ FindFirstScopeOfType(info, ScopeType::CLASS_SCOPE);
+ ASSERT_TRUE(class_scope.has_value());
+
+ // Class scopes accept their start position, because the class context is
+ // already pushed while the source position still points at Token::kClass.
+ DebugScriptScope found =
+ FindInnermostScope(foo, class_scope->start_position());
+ EXPECT_EQ(found.scope_index(), class_scope->scope_index());
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeNestedArrowFunctions) {
+ HandleScope scope(isolate());
+ // Both arrow functions end at the same position, so the tightest fit is
+ // decided by the start position.
+ const char* source = "const f = a => b => a + b;";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script_scope = DebugScriptScope::FromIndex(info, 0);
+ DebugScriptScope found =
+ FindInnermostScope(script_scope, PositionOf(source, "a + b") + 1);
+ EXPECT_EQ(found.scope_index(), 2);
+}
+
+TEST_F(DebugScopeInfoTest, FindInnermostScopeOutsideOfClosureScope) {
+ HandleScope scope(isolate());
+ const char* source = "function foo() { let a = 1; } let b = 2;";
+ ParsedScript parsed = ParseAndSerialize(source);
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope foo = DebugScriptScope::FromIndex(info, 1);
+ // A position that isn't covered by `foo` at all still returns `foo`, there
+ // is nothing tighter to descend into.
+ DebugScriptScope found =
+ FindInnermostScope(foo, PositionOf(source, "let b") + 1);
+ EXPECT_EQ(found.scope_index(), foo.scope_index());
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/diagnostics/etw-control-unittest.cc b/deps/v8/test/unittests/diagnostics/etw-control-unittest.cc
index 78504346050..8aa0a9653d2 100644
--- a/deps/v8/test/unittests/diagnostics/etw-control-unittest.cc
+++ b/deps/v8/test/unittests/diagnostics/etw-control-unittest.cc
@@ -165,10 +165,12 @@ TEST_F(EtwControlTest, EnableWithFilterData) {
size_t schematized_test_filter_size =
sizeof(SchematizedTestFilter) + sizeof(origin_filter) - 1 /*remove '\0'*/;
- std::unique_ptr<SchematizedTestFilter> schematized_test_filter;
- schematized_test_filter.reset(reinterpret_cast<SchematizedTestFilter*>(
- new unsigned char[schematized_test_filter_size]));
- std::memset(schematized_test_filter.get(), 0 /*fill*/,
+ std::unique_ptr<unsigned char[]> schematized_test_filter_buf =
+ std::make_unique<unsigned char[]>(schematized_test_filter_size);
+ SchematizedTestFilter* schematized_test_filter =
+ reinterpret_cast<SchematizedTestFilter*>(
+ schematized_test_filter_buf.get());
+ std::memset(schematized_test_filter, 0 /*fill*/,
schematized_test_filter_size);
std::memcpy(schematized_test_filter->data, origin_filter,
sizeof(origin_filter) - 1 /*remove '\0'*/);
@@ -176,7 +178,7 @@ TEST_F(EtwControlTest, EnableWithFilterData) {
static_cast<ULONG>(schematized_test_filter_size);
event_filter_descriptor.Ptr =
- reinterpret_cast<ULONGLONG>(schematized_test_filter.get());
+ reinterpret_cast<ULONGLONG>(schematized_test_filter);
event_filter_descriptor.Type = EVENT_FILTER_TYPE_SCHEMATIZED;
event_filter_descriptor.Size =
static_cast<ULONG>(schematized_test_filter_size);
@@ -255,10 +257,12 @@ TEST_F(EtwControlTest, EnableWithNonMatchingFilterData) {
size_t schematized_test_filter_size =
sizeof(SchematizedTestFilter) + sizeof(origin_filter) - 1 /*remove '\0'*/;
- std::unique_ptr<SchematizedTestFilter> schematized_test_filter;
- schematized_test_filter.reset(reinterpret_cast<SchematizedTestFilter*>(
- new unsigned char[schematized_test_filter_size]));
- std::memset(schematized_test_filter.get(), 0 /*fill*/,
+ std::unique_ptr<unsigned char[]> schematized_test_filter_buf =
+ std::make_unique<unsigned char[]>(schematized_test_filter_size);
+ SchematizedTestFilter* schematized_test_filter =
+ reinterpret_cast<SchematizedTestFilter*>(
+ schematized_test_filter_buf.get());
+ std::memset(schematized_test_filter, 0 /*fill*/,
schematized_test_filter_size);
std::memcpy(schematized_test_filter->data, origin_filter,
sizeof(origin_filter) - 1 /*remove '\0'*/);
@@ -266,7 +270,7 @@ TEST_F(EtwControlTest, EnableWithNonMatchingFilterData) {
static_cast<ULONG>(schematized_test_filter_size);
event_filter_descriptor.Ptr =
- reinterpret_cast<ULONGLONG>(schematized_test_filter.get());
+ reinterpret_cast<ULONGLONG>(schematized_test_filter);
event_filter_descriptor.Type = EVENT_FILTER_TYPE_SCHEMATIZED;
event_filter_descriptor.Size =
static_cast<ULONG>(schematized_test_filter_size);
@@ -356,10 +360,12 @@ TEST_F(EtwControlTest, EnableWithCustomFilterOnly) {
size_t schematized_test_filter_size =
sizeof(SchematizedTestFilter) + sizeof(origin_filter) - 1 /*remove '\0'*/;
- std::unique_ptr<SchematizedTestFilter> schematized_test_filter;
- schematized_test_filter.reset(reinterpret_cast<SchematizedTestFilter*>(
- new unsigned char[schematized_test_filter_size]));
- std::memset(schematized_test_filter.get(), 0 /*fill*/,
+ std::unique_ptr<unsigned char[]> schematized_test_filter_buf =
+ std::make_unique<unsigned char[]>(schematized_test_filter_size);
+ SchematizedTestFilter* schematized_test_filter =
+ reinterpret_cast<SchematizedTestFilter*>(
+ schematized_test_filter_buf.get());
+ std::memset(schematized_test_filter, 0 /*fill*/,
schematized_test_filter_size);
std::memcpy(schematized_test_filter->data, origin_filter,
sizeof(origin_filter) - 1 /*remove '\0'*/);
@@ -367,7 +373,7 @@ TEST_F(EtwControlTest, EnableWithCustomFilterOnly) {
static_cast<ULONG>(schematized_test_filter_size);
event_filter_descriptor.Ptr =
- reinterpret_cast<ULONGLONG>(schematized_test_filter.get());
+ reinterpret_cast<ULONGLONG>(schematized_test_filter);
event_filter_descriptor.Type = EVENT_FILTER_TYPE_SCHEMATIZED;
event_filter_descriptor.Size =
static_cast<ULONG>(schematized_test_filter_size);
@@ -449,10 +455,12 @@ TEST_F(EtwControlTest, EnableWithNonMatchingCustomFilterOnly) {
size_t schematized_test_filter_size =
sizeof(SchematizedTestFilter) + sizeof(origin_filter) - 1 /*remove '\0'*/;
- std::unique_ptr<SchematizedTestFilter> schematized_test_filter;
- schematized_test_filter.reset(reinterpret_cast<SchematizedTestFilter*>(
- new unsigned char[schematized_test_filter_size]));
- std::memset(schematized_test_filter.get(), 0 /*fill*/,
+ std::unique_ptr<unsigned char[]> schematized_test_filter_buf =
+ std::make_unique<unsigned char[]>(schematized_test_filter_size);
+ SchematizedTestFilter* schematized_test_filter =
+ reinterpret_cast<SchematizedTestFilter*>(
+ schematized_test_filter_buf.get());
+ std::memset(schematized_test_filter, 0 /*fill*/,
schematized_test_filter_size);
std::memcpy(schematized_test_filter->data, origin_filter,
sizeof(origin_filter) - 1 /*remove '\0'*/);
@@ -460,7 +468,7 @@ TEST_F(EtwControlTest, EnableWithNonMatchingCustomFilterOnly) {
static_cast<ULONG>(schematized_test_filter_size);
event_filter_descriptor.Ptr =
- reinterpret_cast<ULONGLONG>(schematized_test_filter.get());
+ reinterpret_cast<ULONGLONG>(schematized_test_filter);
event_filter_descriptor.Type = EVENT_FILTER_TYPE_SCHEMATIZED;
event_filter_descriptor.Size =
static_cast<ULONG>(schematized_test_filter_size);
diff --git a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
index 5b98d617d87..d2d8b1f6277 100644
--- a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
+++ b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
@@ -205,6 +205,30 @@ TEST_P(MicrotaskQueueTest, EnqueueAndRun) {
EXPECT_EQ(0, microtask_queue()->size());
}
+// The public v8::MicrotaskQueue policy accessors control auto-running for
+// this queue, independently of Isolate::SetMicrotasksPolicy().
+TEST_P(MicrotaskQueueTest, SetMicrotasksPolicy) {
+ v8::MicrotaskQueue* api_queue = microtask_queue();
+ api_queue->SetMicrotasksPolicy(MicrotasksPolicy::kExplicit);
+ EXPECT_EQ(MicrotasksPolicy::kExplicit, api_queue->GetMicrotasksPolicy());
+ EXPECT_EQ(MicrotasksPolicy::kExplicit,
+ microtask_queue()->microtasks_policy());
+
+ bool ran = false;
+ Enqueue([&ran] { ran = true; });
+ // With kExplicit, completing a script run does not drain this queue.
+ RunJS("0");
+ EXPECT_FALSE(ran);
+ EXPECT_EQ(1, microtask_queue()->size());
+
+ // With kAuto it does.
+ api_queue->SetMicrotasksPolicy(MicrotasksPolicy::kAuto);
+ EXPECT_EQ(MicrotasksPolicy::kAuto, api_queue->GetMicrotasksPolicy());
+ RunJS("0");
+ EXPECT_TRUE(ran);
+ EXPECT_EQ(0, microtask_queue()->size());
+}
+
// Check for a buffer growth.
TEST_P(MicrotaskQueueTest, BufferGrowth) {
int count = 0;
diff --git a/deps/v8/test/unittests/flags/flag-definitions-unittest.cc b/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
index 2e06620b5d3..bfafc52b831 100644
--- a/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
+++ b/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
@@ -173,6 +173,14 @@ TEST_F(FlagDefinitionsTest, AssignReadOnlyStringFlag) {
CHECK_EQ(0, FlagList::SetFlagsFromString(str, strlen(str)));
}
+TEST_F(FlagDefinitionsTest, RejectNegativeUnsignedFlagAndKeepDefault) {
+ int argc = 2;
+ const char* argv[] = {"Test", "--cpu-profiler-sampling-interval=-100"};
+ CHECK_EQ(1, FlagList::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv),
+ true));
+ CHECK_EQ(1000u, v8_flags.cpu_profiler_sampling_interval.value());
+}
+
TEST_F(FlagDefinitionsTest, FlagsRemoveIncomplete) {
// Test that processed command line arguments are removed, even
// if the list of arguments ends unexpectedly.
diff --git a/deps/v8/test/unittests/heap/cppgc-js/embedder-roots-handler-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/embedder-roots-handler-unittest.cc
index e8c4024b164..2d93a54ac8f 100644
--- a/deps/v8/test/unittests/heap/cppgc-js/embedder-roots-handler-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc-js/embedder-roots-handler-unittest.cc
@@ -43,8 +43,8 @@ class ClearingEmbedderRootsHandler final : public v8::EmbedderRootsHandler {
// in the wrappable field.
BasicTracedReference<v8::Value>* original_handle =
reinterpret_cast<BasicTracedReference<v8::Value>*>(
- v8::Object::Unwrap<CppHeapPointerTag::kTagForTesting>(
- isolate_, handle.As<v8::Object>()));
+ v8::Object::Unwrap<kTagForTesting>(isolate_,
+ handle.As<v8::Object>()));
original_handle->Reset();
}
diff --git a/deps/v8/test/unittests/heap/cppgc-js/traced-reference-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/traced-reference-unittest.cc
index 27d294a20b3..3ec0a4c5f7d 100644
--- a/deps/v8/test/unittests/heap/cppgc-js/traced-reference-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc-js/traced-reference-unittest.cc
@@ -2,12 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "include/cppgc/allocation.h"
+#include "include/cppgc/garbage-collected.h"
+#include "include/cppgc/prefinalizer.h"
#include "include/v8-cppgc.h"
#include "include/v8-traced-handle.h"
#include "src/api/api-inl.h"
+#include "src/base/platform/platform.h"
#include "src/handles/global-handles.h"
+#include "src/heap/cppgc-internal/marker.h"
#include "src/heap/cppgc-internal/visitor.h"
+#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/marking-state-inl.h"
+#include "test/unittests/heap/cppgc-js/unified-heap-utils.h"
#include "test/unittests/heap/heap-utils.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -372,5 +379,138 @@ TEST_F(TracedReferenceTest, WriteBarrierForOnStackMove) {
}
}
+namespace {
+
+// A garbage-collected object that resets its own TracedReference from a
+// pre-finalizer. Blink reaches the same shape via
+// DOMTimer::Dispose() -> ScheduledAction::Dispose().
+class ResettingPreFinalizer final
+ : public cppgc::GarbageCollected<ResettingPreFinalizer> {
+ CPPGC_USING_PRE_FINALIZER(ResettingPreFinalizer, Dispose);
+
+ public:
+ ResettingPreFinalizer(v8::Isolate* isolate, v8::Local<v8::Object> object)
+ : ref_(isolate, object) {}
+
+ void Trace(cppgc::Visitor* visitor) const { visitor->Trace(ref_); }
+
+ void Dispose() { ref_.Reset(); }
+
+ private:
+ v8::TracedReference<v8::Object> ref_;
+};
+
+} // namespace
+
+using TracedReferencePreFinalizerTest = UnifiedHeapTest;
+
+// A pre-finalizer only runs on an object the collector already found to be
+// dead, so that object was never traced, and `ResetDeadNodes()` released its
+// TracedNode earlier in the same atomic pause. If the object's pre-finalizer
+// resets the TracedReference, it would release its TracedNode a second time.
+//
+// Note that the pre-finalizer here does not misuse the API: cppgc documents
+// that a pre-finalizer "may access the whole object graph, irrespective of
+// whether objects are considered dead or alive".
+TEST_F(TracedReferencePreFinalizerTest,
+ PreFinalizerResetDoesNotDoubleFreeNode) {
+ // Settle the heap first so that the node allocated below is the only traced
+ // node dying in the next GC, and hence would become the free list head.
+ CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
+
+ {
+ v8::HandleScope handles(v8_isolate());
+ // Deliberately not rooted: it must be dead by the next GC.
+ cppgc::MakeGarbageCollected<ResettingPreFinalizer>(
+ allocation_handle(), v8_isolate(), v8::Object::New(v8_isolate()));
+ }
+
+ CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
+
+ v8::HandleScope handles(v8_isolate());
+ v8::Local<v8::Object> first = v8::Object::New(v8_isolate());
+ v8::Local<v8::Object> second = v8::Object::New(v8_isolate());
+ ASSERT_TRUE(first != second);
+
+ v8::TracedReference<v8::Object> ref1(v8_isolate(), first);
+ v8::TracedReference<v8::Object> ref2(v8_isolate(), second);
+
+ // The two references must be backed by distinct TracedNodes. With the double
+ // free, creating `ref2` reused `ref1`'s node and overwrote its object.
+ EXPECT_EQ(ref1, first);
+ EXPECT_NE(ref1, ref2);
+}
+
+namespace {
+
+class ConcurrentMarkerThread final : public v8::base::Thread {
+ public:
+ ConcurrentMarkerThread(
+ cppgc::Visitor& visitor,
+ const std::vector<v8::TracedReference<v8::Object>>& refs,
+ std::atomic<bool>& stop)
+ : v8::base::Thread(Options("ConcurrentMarkerThread")),
+ visitor_(visitor),
+ refs_(refs),
+ stop_(stop) {}
+
+ void Run() override {
+ while (!stop_.load(std::memory_order_relaxed)) {
+ for (const auto& ref : refs_) {
+ visitor_.Trace(ref);
+ }
+ }
+ }
+
+ private:
+ cppgc::Visitor& visitor_;
+ const std::vector<v8::TracedReference<v8::Object>>& refs_;
+ std::atomic<bool>& stop_;
+};
+
+} // namespace
+
+using TracedReferenceUnifiedHeapTest = UnifiedHeapTest;
+
+TEST_F(TracedReferenceUnifiedHeapTest, Regress40059554) {
+ // Regression test: https://crbug.com/40059554
+ if (!v8_flags.incremental_marking) return;
+
+ static constexpr size_t kNumHandles = 8192;
+ v8::HandleScope scope(v8_isolate());
+ v8::Local<v8::Object> obj = v8::Object::New(v8_isolate());
+ std::vector<v8::TracedReference<v8::Object>> refs(kNumHandles);
+
+ // Populate TracedNodeBlock free lists with zapped nodes.
+ for (auto& ref : refs) {
+ ref.Reset(v8_isolate(), obj);
+ }
+ for (auto& ref : refs) {
+ ref.Reset();
+ }
+
+ SimulateIncrementalMarking(false);
+
+ std::atomic<bool> stop{false};
+ ConcurrentMarkerThread marker_thread(cpp_heap().AsBase().marker()->Visitor(),
+ refs, stop);
+ CHECK(marker_thread.Start());
+
+ // Create new references while the concurrent marker is already active. This
+ // stress-tests the publication of the new traced handle's node.
+ for (auto& ref : refs) {
+ ref.Reset(v8_isolate(), obj);
+ }
+
+ // Anything below this point is just cleanup. The crash would have already
+ // ocurred before the concurrent thread is stopped.
+ stop.store(true, std::memory_order_relaxed);
+ marker_thread.Join();
+
+ for (auto& ref : refs) {
+ ref.Reset();
+ }
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-snapshot-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-snapshot-unittest.cc
index 08bc3da71c3..76fd2ee5b6c 100644
--- a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-snapshot-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-snapshot-unittest.cc
@@ -1254,9 +1254,8 @@ TEST_F(UnifiedHeapSnapshotTest, CppHeapExternal) {
auto* cpp_object =
cppgc::MakeGarbageCollected<ExternalData>(allocation_handle());
v8::Global<v8::CppHeapExternal> cpp_heap_external(
- v8_isolate(),
- v8::CppHeapExternal::New<ExternalData>(
- v8_isolate(), cpp_object, v8::CppHeapPointerTag::kTagForTesting));
+ v8_isolate(), v8::CppHeapExternal::New<ExternalData>(
+ v8_isolate(), cpp_object, kTagForTesting));
USE(cpp_heap_external);
const v8::HeapSnapshot* snapshot =
TakeHeapSnapshot(cppgc::EmbedderStackState::kNoHeapPointers);
@@ -1394,7 +1393,7 @@ TEST_F(UnifiedHeapSnapshotTest, CppHeapExternalTracedReference) {
v8::CppHeapExternal::New<ExternalData>(
v8_isolate(),
cppgc::MakeGarbageCollected<ExternalData>(allocation_handle()),
- v8::CppHeapPointerTag::kTagForTesting));
+ kTagForTesting));
const v8::HeapSnapshot* snapshot =
TakeHeapSnapshot(cppgc::EmbedderStackState::kNoHeapPointers);
EXPECT_TRUE(IsValidSnapshot(snapshot));
diff --git a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc
index 9e172c18ae6..a43348eb53b 100644
--- a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc
@@ -805,7 +805,6 @@ TEST_F(UnifiedHeapTest, CppgcSweepingDuringMinorV8Sweeping) {
Heap* heap = isolate()->heap();
CppHeap* cppheap = CppHeap::From(heap->cpp_heap());
cppheap->UpdateGCCapabilitiesFromFlagsForTesting();
- CHECK_NOT_NULL(heap->cpp_heap());
heap->CollectGarbage(AllocationSpace::OLD_SPACE,
GarbageCollectionReason::kTesting,
GCCallbackFlags::kNoGCCallbackFlags);
diff --git a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-utils.cc b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-utils.cc
index df2a1044edd..142cdea4eaa 100644
--- a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-utils.cc
+++ b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-utils.cc
@@ -50,7 +50,7 @@ void WrapperHelper::ResetWrappableConnection(v8::Isolate* isolate,
v8::Utils::OpenDirectHandle(*api_object);
CppHeapObjectWrapper(Cast<JSObject>(*js_obj))
.SetCppHeapWrappable(reinterpret_cast<i::Isolate*>(isolate), nullptr,
- CppHeapPointerTag::kTagForTesting);
+ kTagForTesting);
}
// static
@@ -61,7 +61,7 @@ void WrapperHelper::SetWrappableConnection(v8::Isolate* isolate,
v8::Utils::OpenDirectHandle(*api_object);
CppHeapObjectWrapper(Cast<JSObject>(*js_obj))
.SetCppHeapWrappable(reinterpret_cast<i::Isolate*>(isolate), instance,
- CppHeapPointerTag::kTagForTesting);
+ kTagForTesting);
}
// static
diff --git a/deps/v8/test/unittests/heap/gc-tracer-unittest.cc b/deps/v8/test/unittests/heap/gc-tracer-unittest.cc
index bcde0440e28..0a3c311f01f 100644
--- a/deps/v8/test/unittests/heap/gc-tracer-unittest.cc
+++ b/deps/v8/test/unittests/heap/gc-tracer-unittest.cc
@@ -78,21 +78,21 @@ void StopTracing(Heap* heap, GarbageCollector collector,
case GarbageCollector::MINOR_MARK_SWEEPER:
tracer->NotifyYoungSweepingCompletedAndStopCycleIfFinished();
break;
- case GarbageCollector::MARK_COMPACTOR:
- if (heap->cpp_heap()) {
- using namespace cppgc::internal;
- CppHeap* cpp_heap = CppHeap::From(heap->cpp_heap());
- cpp_heap->object_allocator().ResetLinearAllocationBuffers();
- StatsCollector* stats_collector = cpp_heap->stats_collector();
- stats_collector->NotifyMarkingStarted(
- CollectionType::kMajor, cppgc::Heap::MarkingType::kAtomic,
- MarkingConfig::IsForcedGC::kNotForced);
- stats_collector->NotifyMarkingCompleted(0);
- stats_collector->NotifySweepingCompleted(
- cppgc::Heap::SweepingType::kAtomic);
- }
+ case GarbageCollector::MARK_COMPACTOR: {
+ CppHeap* cpp_heap = CppHeap::From(heap->cpp_heap());
+ cpp_heap->object_allocator().ResetLinearAllocationBuffers();
+ cppgc::internal::StatsCollector* stats_collector =
+ cpp_heap->stats_collector();
+ stats_collector->NotifyMarkingStarted(
+ cppgc::internal::CollectionType::kMajor,
+ cppgc::Heap::MarkingType::kAtomic,
+ cppgc::internal::MarkingConfig::IsForcedGC::kNotForced);
+ stats_collector->NotifyMarkingCompleted(0);
+ stats_collector->NotifySweepingCompleted(
+ cppgc::Heap::SweepingType::kAtomic);
tracer->NotifyFullSweepingCompletedAndStopCycleIfFinished();
break;
+ }
}
}
diff --git a/deps/v8/test/unittests/heap/heap-unittest.cc b/deps/v8/test/unittests/heap/heap-unittest.cc
index 1dbbb2b1b8f..850bfa9f06b 100644
--- a/deps/v8/test/unittests/heap/heap-unittest.cc
+++ b/deps/v8/test/unittests/heap/heap-unittest.cc
@@ -37,7 +37,9 @@
#include "src/heap/heap-controller.h"
#include "src/heap/heap-layout-inl.h"
#include "src/heap/heap-layout.h"
+#include "src/heap/large-page-inl.h"
#include "src/heap/main-allocator-inl.h"
+#include "src/heap/marking-barrier.h"
#include "src/heap/marking-state-inl.h"
#include "src/heap/minor-mark-sweep.h"
#include "src/heap/mutable-page.h"
@@ -449,17 +451,14 @@ void ShrinkNewSpace(NewSpace* new_space) {
tracer->StopAtomicPause();
tracer->StopObservablePause(GarbageCollector::MARK_COMPACTOR,
base::TimeTicks::Now());
- if (heap->cpp_heap()) {
- cppgc::internal::StatsCollector* stats_collector =
- CppHeap::From(heap->cpp_heap())->stats_collector();
- stats_collector->NotifyMarkingStarted(
- cppgc::internal::CollectionType::kMajor,
- cppgc::Heap::MarkingType::kAtomic,
- cppgc::internal::MarkingConfig::IsForcedGC::kNotForced);
- stats_collector->NotifyMarkingCompleted(0);
- stats_collector->NotifySweepingCompleted(
- cppgc::Heap::SweepingType::kAtomic);
- }
+ cppgc::internal::StatsCollector* stats_collector =
+ CppHeap::From(heap->cpp_heap())->stats_collector();
+ stats_collector->NotifyMarkingStarted(
+ cppgc::internal::CollectionType::kMajor,
+ cppgc::Heap::MarkingType::kAtomic,
+ cppgc::internal::MarkingConfig::IsForcedGC::kNotForced);
+ stats_collector->NotifyMarkingCompleted(0);
+ stats_collector->NotifySweepingCompleted(cppgc::Heap::SweepingType::kAtomic);
tracer->NotifyFullSweepingCompletedAndStopCycleIfFinished();
}
} // namespace
@@ -4397,5 +4396,431 @@ TEST_F(HeapTest, EnsureAllocationSiteDependentCodesProcessed) {
EXPECT_TRUE(site->dependent_code()->Get(0).IsCleared());
}
+void CheckEqualSharedFunctionInfos(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ DirectHandle<Object> obj1 = v8::Utils::OpenDirectHandle(*info[0]);
+ DirectHandle<Object> obj2 = v8::Utils::OpenDirectHandle(*info[1]);
+ DirectHandle<JSFunction> fun1 = Cast<JSFunction>(obj1);
+ DirectHandle<JSFunction> fun2 = Cast<JSFunction>(obj2);
+ CHECK_EQ(fun1->shared(), fun2->shared());
+}
+
+void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(i::ValidateCallbackInfo(info));
+ Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ DirectHandle<Object> obj = v8::Utils::OpenDirectHandle(*info[0]);
+ DirectHandle<JSFunction> fun = Cast<JSFunction>(obj);
+ // Bytecode is code too.
+ SharedFunctionInfo::DiscardCompiled(isolate,
+ direct_handle(fun->shared(), isolate));
+ fun->UpdateCode(isolate, *BUILTIN_CODE(isolate, CompileLazy));
+ InvokeMemoryReducingMajorGCs(isolate);
+}
+
+TEST_F(HeapTest, CanonicalSharedFunctionInfo) {
+ SetGlobalProperty(
+ "check", v8::Function::New(v8_context(), CheckEqualSharedFunctionInfos)
+ .ToLocalChecked());
+ SetGlobalProperty(
+ "remove",
+ v8::Function::New(v8_context(), RemoveCodeAndGC).ToLocalChecked());
+ RunJS(
+ "function f() { return function g() {}; }\n"
+ "var g1 = f();\n"
+ "remove(f);\n"
+ "var g2 = f();\n"
+ "check(g1, g2);\n");
+
+ RunJS(
+ "function f() { return (function() { return function g() {}; })(); }\n"
+ "var g1 = f();\n"
+ "remove(f);\n"
+ "var g2 = f();\n"
+ "check(g1, g2);\n");
+}
+
+TEST_F(HeapTest, ScriptIterator) {
+ v8::HandleScope scope(v8_isolate());
+
+ InvokeMajorGC();
+
+ int script_count = 0;
+ {
+ HeapObjectIterator it(heap());
+ for (Tagged<HeapObject> obj = it.Next(); !obj.is_null(); obj = it.Next()) {
+ if (IsScript(obj)) script_count++;
+ }
+ }
+
+ {
+ Script::Iterator iterator(i_isolate());
+ for (Tagged<Script> script = iterator.Next(); !script.is_null();
+ script = iterator.Next()) {
+ script_count--;
+ }
+ }
+
+ EXPECT_EQ(0, script_count);
+}
+
+TEST_F(HeapTest, Regress587004) {
+ if (v8_flags.single_generation) return;
+ ManualGCScope manual_gc_scope(i_isolate());
+#ifdef VERIFY_HEAP
+ v8_flags.verify_heap = false;
+#endif
+ HandleScope scope(i_isolate());
+ Heap* heap = this->heap();
+ Isolate* isolate = this->i_isolate();
+ Factory* factory = isolate->factory();
+ const int N = (kMaxRegularHeapObjectSize - OFFSET_OF_DATA_START(FixedArray)) /
+ kTaggedSize;
+ DirectHandle<FixedArray> array =
+ factory->NewFixedArray(N, AllocationType::kOld);
+ CHECK(heap->old_space()->Contains(*array));
+ DirectHandle<Object> number = factory->NewHeapNumber(1.0);
+ CHECK(HeapLayout::InYoungGeneration(*number));
+ for (int i = 0; i < N; i++) {
+ array->set(i, *number);
+ }
+ InvokeMajorGC();
+ SimulateFullSpace(heap->old_space());
+ heap->RightTrimArray(*array, 1, N);
+ heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ Tagged<ByteArray> byte_array;
+ const uint32_t M = 256;
+ // Don't allow old space expansion. The test works without this flag too,
+ // but becomes very slow.
+ SetForceOOM(heap, true);
+ while (
+ AllocateByteArrayForTest(heap, M, AllocationType::kOld).To(&byte_array)) {
+ for (uint32_t j = 0; j < M; j++) {
+ byte_array->set(j, 0x31);
+ }
+ }
+ // Re-enable old space expansion to avoid OOM crash.
+ SetForceOOM(heap, false);
+ InvokeMinorGC();
+}
+
+TEST_F(HeapTest, Regress589413) {
+ if (!v8_flags.incremental_marking || v8_flags.stress_concurrent_allocation) {
+ return;
+ }
+ v8_flags.stress_compaction = true;
+ ManualGCScope manual_gc_scope(i_isolate());
+ v8_flags.manual_evacuation_candidates_selection = true;
+ v8_flags.parallel_compaction = false;
+ HandleScope scope(i_isolate());
+ Heap* heap = this->heap();
+ // Get the heap in clean state.
+ InvokeMajorGC();
+ InvokeMajorGC();
+ Isolate* isolate = i_isolate();
+ Factory* factory = isolate->factory();
+
+ auto force_evacuation_candidate = [](NormalPage* page) {
+ Isolate* isolate = page->owner()->heap()->isolate();
+ SafepointScope safepoint(isolate, kGlobalSafepointForSharedSpaceIsolate);
+ CHECK(v8_flags.manual_evacuation_candidates_selection);
+ page->set_forced_evacuation_candidate_for_testing(true);
+ page->owner()->heap()->FreeLinearAllocationAreas();
+ };
+
+ // Fill the new space with byte arrays with elements looking like pointers.
+ const uint32_t M = 256;
+ Tagged<ByteArray> byte_array;
+ NormalPage* young_page = nullptr;
+ while (AllocateByteArrayForTest(heap, M, AllocationType::kYoung)
+ .To(&byte_array)) {
+ // Only allocate objects on one young page as a rough estimate on
+ // how much memory can be promoted into the old generation.
+ // Otherwise we would crash when forcing promotion of all young
+ // live objects.
+ if (!young_page) young_page = NormalPage::FromHeapObject(byte_array);
+ if (NormalPage::FromHeapObject(byte_array) != young_page) break;
+
+ for (uint32_t j = 0; j < M; j++) {
+ byte_array->set(j, 0x31);
+ }
+ // Add the array in root set.
+ handle(byte_array, isolate);
+ }
+ auto reset_oom = [](void* data, size_t limit, size_t) -> size_t {
+ HeapTest* test = static_cast<HeapTest*>(data);
+ test->SetForceOOM(test->heap(), false);
+ return limit;
+ };
+ heap->AddNearHeapLimitCallback(reset_oom, this);
+
+ {
+ // Ensure that incremental marking is not started unexpectedly.
+ AlwaysAllocateScopeForTesting always_allocate(isolate->heap());
+
+ // Make sure the byte arrays will be promoted on the next GC.
+ InvokeMinorGC();
+ // This number is close to large free list category threshold.
+ const uint32_t N = 0x3EEE;
+
+ std::vector<Tagged<FixedArray>> arrays;
+ std::set<NormalPage*> pages;
+ Tagged<FixedArray> array;
+ // Fill all pages with fixed arrays.
+ SetForceOOM(heap, true);
+ while (
+ AllocateFixedArrayForTest(heap, N, AllocationType::kOld).To(&array)) {
+ arrays.push_back(array);
+ pages.insert(NormalPage::FromHeapObject(array));
+ // Add the array in root set.
+ handle(array, isolate);
+ }
+ SetForceOOM(heap, false);
+ size_t initial_pages = pages.size();
+ // Expand and fill two pages with fixed array to ensure enough space both
+ // the young objects and the evacuation candidate pages.
+ while (
+ AllocateFixedArrayForTest(heap, N, AllocationType::kOld).To(&array)) {
+ arrays.push_back(array);
+ pages.insert(NormalPage::FromHeapObject(array));
+ // Add the array in root set.
+ handle(array, isolate);
+ // Do not expand anymore.
+ if (pages.size() - initial_pages == 2) {
+ SetForceOOM(heap, true);
+ }
+ }
+ // Expand and mark the new page as evacuation candidate.
+ SetForceOOM(heap, false);
+ {
+ DirectHandle<HeapObject> ec_obj =
+ factory->NewFixedArray(5000, AllocationType::kOld);
+ NormalPage* ec_page = NormalPage::FromHeapObject(*ec_obj);
+ force_evacuation_candidate(ec_page);
+ // Make all arrays point to evacuation candidate so that
+ // slots are recorded for them.
+ for (size_t j = 0; j < arrays.size(); j++) {
+ array = arrays[j];
+ for (uint32_t i = 0; i < N; i++) {
+ array->set(i, *ec_obj);
+ }
+ }
+ }
+ CHECK(heap->incremental_marking()->IsStopped());
+ SimulateIncrementalMarking();
+ for (size_t j = 0; j < arrays.size(); j++) {
+ heap->RightTrimArray(arrays[j], 1, N);
+ }
+ }
+
+ // Force allocation from the free list.
+ SetForceOOM(heap, true);
+ InvokeMajorGC();
+ heap->RemoveNearHeapLimitCallback(reset_oom, 0);
+}
+
+TEST_F(HeapTest, Regress598319) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(i_isolate());
+ // This test ensures that no white objects can cross the progress bar of large
+ // objects during incremental marking. It checks this by using Shift() during
+ // incremental marking.
+ v8::HandleScope scope(v8_isolate());
+ Heap* heap = this->heap();
+ Isolate* isolate = i_isolate();
+
+ // The size of the array should be larger than kProgressBarScanningChunk.
+ const uint32_t kNumberOfObjects =
+ std::max(FixedArray::kMaxRegularLength + 1, 128 * KB);
+
+ struct Arr {
+ Arr(Isolate* isolate, v8::Isolate* v8_isolate, uint32_t number_of_objects) {
+ root = isolate->factory()->NewFixedArray(1, AllocationType::kOld);
+ {
+ // Temporary scope to avoid getting any other objects into the root set.
+ v8::HandleScope new_scope(v8_isolate);
+ DirectHandle<FixedArray> tmp = isolate->factory()->NewFixedArray(
+ number_of_objects, AllocationType::kOld);
+ root->set(0, *tmp);
+ const uint32_t length = get()->length().value();
+ for (uint32_t i = 0; i < length; i++) {
+ tmp = isolate->factory()->NewFixedArray(100, AllocationType::kOld);
+ get()->set(i, *tmp);
+ }
+ }
+ global_root.Reset(v8_isolate, Utils::ToLocal(Cast<Object>(root)));
+ }
+
+ Tagged<FixedArray> get() { return Cast<FixedArray>(root->get(0)); }
+
+ Handle<FixedArray> root;
+
+ // Store array in global as well to make it part of the root set when
+ // starting incremental marking.
+ v8::Global<Value> global_root;
+ } arr(isolate, v8_isolate(), kNumberOfObjects);
+
+ CHECK_EQ(arr.get()->length().value(), kNumberOfObjects);
+ CHECK(heap->lo_space()->Contains(arr.get()));
+ LargePage* page = LargePage::FromHeapObject(isolate, arr.get());
+ CHECK_NOT_NULL(page);
+
+ // GC to cleanup state
+ InvokeMajorGC();
+ if (heap->sweeping_in_progress()) {
+ heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+
+ CHECK(heap->lo_space()->Contains(arr.get()));
+ IncrementalMarking* marking = heap->incremental_marking();
+ MarkingState* marking_state = heap->marking_state();
+ CHECK(marking_state->IsUnmarked(arr.get()));
+
+ for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
+ Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
+ CHECK(marking_state->IsUnmarked(arr_value));
+ }
+
+ // Start incremental marking.
+ CHECK(marking->IsMarking() || marking->IsStopped());
+ if (marking->IsStopped()) {
+ heap->StartIncrementalMarking(i::GCFlag::kNoFlags,
+ i::GarbageCollectionReason::kTesting);
+ }
+ CHECK(marking->IsMarking());
+
+ // Check that we have not marked the interesting array during root scanning.
+ for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
+ Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
+ CHECK(marking_state->IsUnmarked(arr_value));
+ }
+
+ // Now we search for a state where we are in incremental marking and have
+ // only partially marked the large object.
+ static constexpr auto kSmallStepSize =
+ v8::base::TimeDelta::FromMillisecondsD(0.1);
+ static constexpr size_t kSmallMaxBytesToMark = 100;
+ while (!marking->IsMajorMarkingComplete()) {
+ marking->AdvanceForTesting(kSmallStepSize, kSmallMaxBytesToMark);
+ MarkingProgressTracker& progress_tracker = page->marking_progress_tracker();
+ if (progress_tracker.IsEnabled() &&
+ progress_tracker.GetCurrentChunkForTesting() > 0) {
+ CHECK_NE(progress_tracker.GetCurrentChunkForTesting(), arr.get()->Size());
+ {
+ // Shift by 1, effectively moving one white object across the progress
+ // bar, meaning that we will miss marking it.
+ v8::HandleScope new_scope(v8_isolate());
+ DirectHandle<JSArray> js_array =
+ isolate->factory()->NewJSArrayWithElements(
+ DirectHandle<FixedArray>(arr.get(), isolate));
+ js_array->GetElementsAccessor()->Shift(isolate, js_array);
+ }
+ break;
+ }
+ }
+
+ SafepointScope safepoint_scope(heap->isolate(),
+ kGlobalSafepointForSharedSpaceIsolate);
+ MarkingBarrier::PublishAll(heap);
+
+ // Finish marking with bigger steps to speed up test.
+ static constexpr auto kLargeStepSize =
+ v8::base::TimeDelta::FromMilliseconds(1000);
+ while (!marking->IsMajorMarkingComplete()) {
+ marking->AdvanceForTesting(kLargeStepSize);
+ }
+ CHECK(marking->IsMajorMarkingComplete());
+
+ // All objects need to be black after marking. If a white object crossed the
+ // progress bar, we would fail here.
+ for (uint32_t i = 0; i < arr.get()->length().value(); i++) {
+ Tagged<HeapObject> arr_value = Cast<HeapObject>(arr.get()->get(i));
+ CHECK(HeapLayout::InReadOnlySpace(arr_value) ||
+ marking_state->IsMarked(arr_value));
+ }
+}
+
+DirectHandle<FixedArray> ShrinkArrayAndCheckSize(Heap* heap, int length) {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ // Make sure there is no garbage and the compilation cache is empty.
+ for (int i = 0; i < 5; i++) {
+ InvokeMajorGC(heap->isolate());
+ }
+ heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ // Disable LAB, such that calculations with SizeOfObjects() and object size
+ // are correct.
+ heap->DisableInlineAllocation();
+ size_t size_before_allocation = heap->SizeOfObjects();
+ IndirectHandle<FixedArray> array(
+ *heap->isolate()->factory()->NewFixedArray(length, AllocationType::kOld),
+ heap->isolate());
+ size_t size_after_allocation = heap->SizeOfObjects();
+ CHECK_EQ(size_after_allocation, size_before_allocation + array->Size());
+ array->RightTrim(heap->isolate(), 1);
+ size_t size_after_shrinking = heap->SizeOfObjects();
+ // Shrinking does not change the space size immediately.
+ CHECK_EQ(size_after_allocation, size_after_shrinking);
+ // GC and sweeping updates the size to account for shrinking.
+ InvokeMajorGC(heap->isolate());
+ heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ intptr_t size_after_gc = heap->SizeOfObjects();
+ CHECK_EQ(size_after_gc, size_before_allocation + array->Size());
+ return array;
+}
+
+TEST_F(HeapTest, Regress609761) {
+ ManualGCScope manual_gc_scope(i_isolate());
+ int length = kMaxRegularHeapObjectSize / kTaggedSize + 1;
+ DirectHandle<FixedArray> array = ShrinkArrayAndCheckSize(heap(), length);
+ CHECK(heap()->lo_space()->Contains(*array));
+}
+
+TEST_F(HeapTest, LiveBytes) {
+ ManualGCScope manual_gc_scope(i_isolate());
+ DirectHandle<FixedArray> array = ShrinkArrayAndCheckSize(heap(), 2000);
+ CHECK(heap()->old_space()->Contains(*array));
+}
+
+TEST_F(HeapTest, Regress615489) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(i_isolate());
+ HandleScope scope(i_isolate());
+ Heap* heap = this->heap();
+ Isolate* isolate = i_isolate();
+ InvokeMajorGC();
+
+ IncrementalMarking* marking = heap->incremental_marking();
+ if (heap->sweeping_in_progress()) {
+ heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+ CHECK(marking->IsMarking() || marking->IsStopped());
+ if (marking->IsStopped()) {
+ heap->StartIncrementalMarking(GCFlag::kNoFlags,
+ GarbageCollectionReason::kTesting);
+ }
+ CHECK(marking->IsMarking());
+ CHECK(marking->black_allocation());
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap);
+ HandleScope inner(isolate);
+ isolate->factory()->NewFixedArray(500, AllocationType::kOld)->Size();
+ }
+ static constexpr auto kStepSize = v8::base::TimeDelta::FromMilliseconds(100);
+ while (!marking->IsMajorMarkingComplete()) {
+ marking->AdvanceForTesting(kStepSize);
+ }
+ CHECK(marking->IsMajorMarkingComplete());
+ size_t size_before = heap->SizeOfObjects();
+ InvokeMajorGC();
+ size_t size_after = heap->SizeOfObjects();
+ // Live size does not increase after garbage collection.
+ CHECK_LE(size_after, size_before);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/heap-utils.cc b/deps/v8/test/unittests/heap/heap-utils.cc
index 4726f1c4139..13f8ea9afce 100644
--- a/deps/v8/test/unittests/heap/heap-utils.cc
+++ b/deps/v8/test/unittests/heap/heap-utils.cc
@@ -18,22 +18,14 @@
#include "src/heap/normal-page-inl.h"
#include "src/heap/safepoint.h"
#include "src/heap/spaces-inl.h"
+#include "src/objects/fixed-primitive-array-inl.h"
#include "src/objects/free-space-inl.h"
namespace v8 {
namespace internal {
-namespace heap {
-class HeapTester {
- public:
- static size_t OldGenerationSpaceAvailable(Heap* heap) {
- return heap->OldGenerationSpaceAvailable();
- }
-};
-} // namespace heap
-
size_t HeapInternalsBase::OldGenerationSpaceAvailable(Heap* heap) {
- return heap::HeapTester::OldGenerationSpaceAvailable(heap);
+ return heap->OldGenerationSpaceAvailable();
}
void HeapInternalsBase::SimulateIncrementalMarking(Heap* heap,
@@ -351,7 +343,7 @@ ManualGCScope::ManualGCScope(Isolate* isolate)
// CppHeap concurrent marking has a dependency on concurrent marking.
v8_flags.cppheap_concurrent_marking = false;
- if (isolate_ && isolate_->heap()->cpp_heap()) {
+ if (isolate_) {
CppHeap::From(isolate_->heap()->cpp_heap())
->UpdateGCCapabilitiesFromFlagsForTesting();
}
@@ -368,7 +360,7 @@ ManualGCScope::~ManualGCScope() {
flag_detect_ineffective_gcs_near_heap_limit_;
v8_flags.cppheap_concurrent_marking = flag_cppheap_concurrent_marking_;
- if (isolate_ && isolate_->heap()->cpp_heap()) {
+ if (isolate_) {
CppHeap::From(isolate_->heap()->cpp_heap())
->UpdateGCCapabilitiesFromFlagsForTesting();
}
@@ -418,5 +410,45 @@ void ForceEvacuationCandidate(NormalPage* page) {
page->owner()->heap()->FreeLinearAllocationAreas();
}
+AllocationResult HeapInternalsBase::AllocateByteArrayForTest(
+ Heap* heap, uint32_t length, AllocationType allocation_type) {
+ DCHECK_LE(length, ByteArray::kMaxLength);
+ int size = ByteArray::SizeFor(length);
+ Tagged<HeapObject> result;
+ {
+ AllocationResult allocation = heap->AllocateRaw(size, allocation_type);
+ if (!allocation.To(&result)) return allocation;
+ }
+
+ result->set_map_after_allocation(heap->isolate(),
+ ReadOnlyRoots(heap).byte_array_map(),
+ SKIP_WRITE_BARRIER);
+ Cast<ByteArray>(result)->set_length(length);
+ return AllocationResult::FromObject(result);
+}
+
+AllocationResult HeapInternalsBase::AllocateFixedArrayForTest(
+ Heap* heap, uint32_t length, AllocationType allocation) {
+ DCHECK_LE(length, FixedArray::kMaxLength);
+ int size = FixedArray::SizeFor(length);
+ Tagged<HeapObject> obj;
+ {
+ AllocationResult result = heap->AllocateRaw(size, allocation);
+ if (!result.To(&obj)) return result;
+ }
+ obj->set_map_after_allocation(heap->isolate(),
+ ReadOnlyRoots(heap).fixed_array_map(),
+ SKIP_WRITE_BARRIER);
+ Tagged<FixedArray> array = Cast<FixedArray>(obj);
+ array->set_length(length);
+ MemsetTagged(array->RawFieldOfFirstElement(),
+ ReadOnlyRoots(heap).undefined_value(), length);
+ return AllocationResult::FromObject(array);
+}
+
+void HeapInternalsBase::SetForceOOM(Heap* heap, bool value) {
+ heap->set_force_oom(value);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/heap-utils.h b/deps/v8/test/unittests/heap/heap-utils.h
index 08f76472f73..7e867ec19b4 100644
--- a/deps/v8/test/unittests/heap/heap-utils.h
+++ b/deps/v8/test/unittests/heap/heap-utils.h
@@ -31,6 +31,11 @@ class HeapInternalsBase {
void FillCurrentPageButNBytes(
v8::internal::SemiSpaceNewSpace* space, int extra_bytes,
std::vector<Handle<FixedArray>>* out_handles = nullptr);
+ AllocationResult AllocateByteArrayForTest(Heap* heap, uint32_t length,
+ AllocationType allocation_type);
+ AllocationResult AllocateFixedArrayForTest(Heap* heap, uint32_t length,
+ AllocationType allocation);
+ void SetForceOOM(Heap* heap, bool value);
};
inline void InvokeMajorGC(i::Isolate* isolate) {
@@ -127,6 +132,20 @@ class WithHeapInternals : public TMixin, HeapInternalsBase {
out_handles);
}
+ AllocationResult AllocateByteArrayForTest(Heap* heap, uint32_t length,
+ AllocationType allocation_type) {
+ return HeapInternalsBase::AllocateByteArrayForTest(heap, length,
+ allocation_type);
+ }
+ AllocationResult AllocateFixedArrayForTest(Heap* heap, uint32_t length,
+ AllocationType allocation) {
+ return HeapInternalsBase::AllocateFixedArrayForTest(heap, length,
+ allocation);
+ }
+ void SetForceOOM(Heap* heap, bool value) {
+ HeapInternalsBase::SetForceOOM(heap, value);
+ }
+
void GrowNewSpaceToMaximumCapacity() {
IsolateSafepointScope scope(heap());
NewSpace* new_space = heap()->new_space();
diff --git a/deps/v8/test/unittests/inspector/inspector-unittest.cc b/deps/v8/test/unittests/inspector/inspector-unittest.cc
index 7e08be739bf..ddbcf769416 100644
--- a/deps/v8/test/unittests/inspector/inspector-unittest.cc
+++ b/deps/v8/test/unittests/inspector/inspector-unittest.cc
@@ -401,14 +401,6 @@ class UAFTriggerChannel : public V8Inspector::Channel {
m_triggerCount++;
m_inspector->resetContextGroup(m_contextGroupId);
- // Allocate a few small dummy blocks of varying sizes
- // and prevent the allocator from recycling the same memory address,
- // otherwise our test NoUAFWhenResettingContextGroupDuringArgumentWrapping
- // will actually report the message to the front-end.
- for (size_t size : {32, 48, 64, 80, 96, 128, 256}) {
- m_dummies.push_back(std::make_unique<std::vector<uint8_t>>(size, 0));
- }
-
// Recreate storage using public exceptionThrown API.
// This avoids depending on internal non-exported V8InspectorImpl methods.
v8::HandleScope handle_scope(m_isolate);
@@ -447,7 +439,6 @@ class UAFTriggerChannel : public V8Inspector::Channel {
std::string m_targetNotification;
int m_triggerCount = 0;
bool m_consoleAPICalled = false;
- std::vector<std::unique_ptr<std::vector<uint8_t>>> m_dummies;
};
TEST_F(InspectorTest, NoUAFWhenResettingContextGroupDuringMessageReporting) {
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
index 2ce70d9b874..1a98ec1c0ee 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
@@ -88,6 +88,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreAccumulatorInRegister(reg)
.LoadTheHole()
.StoreAccumulatorInRegister(reg)
+ .LoadTdzHole()
+ .StoreAccumulatorInRegister(reg)
.LoadTrue()
.StoreAccumulatorInRegister(reg)
.LoadFalse()
@@ -245,6 +247,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.SetKeyedProperty(reg, reg, strict_keyed_store_slot.ToInt(),
LanguageMode::kStrict)
.DefineNamedOwnProperty(reg, name, define_named_own_slot.ToInt())
+ .DefineNamedOwnPropertyInLiteral(reg, name, define_named_own_slot.ToInt())
.DefineKeyedOwnProperty(reg, reg, DefineKeyedOwnPropertyFlag::kNoFlags,
define_named_own_slot.ToInt())
.StoreInArrayLiteral(reg, reg, store_array_element_slot.ToInt())
@@ -408,9 +411,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.ThrowIfNotSuperConstructor(reg);
// Hole checks.
- builder.ThrowReferenceErrorIfHole(name)
- .ThrowSuperAlreadyCalledIfNotHole()
- .ThrowSuperNotCalledIfHole();
+ builder.ThrowReferenceErrorIfTdzHole(name)
+ .ThrowSuperAlreadyCalledIfNotTdzHole()
+ .ThrowSuperNotCalledIfTdzHole();
// Short jumps with Imm8 operands
{
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
index 45ee70bde6a..268db9545db 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
@@ -667,7 +667,7 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(41),
B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
B(Star2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
index c1ab9bc2097..03d1fab8041 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
@@ -101,7 +101,7 @@ bytecode array length: 27
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
B(Star1),
@@ -140,13 +140,13 @@ bytecode array length: 51
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 S> */ B(LdaSmi), I8(1),
/* 42 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(CreateBlockContext), U8(1:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
B(Star1),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ClassAndSuperClass.golden
index 78a01670022..3236c40e499 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ClassAndSuperClass.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ClassAndSuperClass.golden
@@ -105,12 +105,12 @@ bytecodes: [
/* 118 E> */ B(Construct), R(4), R(5), RegCount8(1), FBV(0),
B(Star4),
B(Ldar), R(this),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Mov), R(4), R(this),
/* 128 S> */ B(LdaSmi), I8(2),
/* 136 E> */ B(SetNamedProperty), R(this), U8(0:"y_"), FBV(2),
B(Ldar), R(this),
- B(ThrowSuperNotCalledIfHole),
+ B(ThrowSuperNotCalledIfTdzHole),
/* 141 S> */ B(Return),
]
constant pool: [
@@ -148,12 +148,12 @@ bytecodes: [
/* 117 E> */ B(Construct), R(4), R(0), RegCount8(0), FBV(0),
B(Star4),
B(Ldar), R(this),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Mov), R(4), R(this),
/* 126 S> */ B(LdaSmi), I8(2),
/* 134 E> */ B(SetNamedProperty), R(this), U8(0:"y_"), FBV(2),
B(Ldar), R(this),
- B(ThrowSuperNotCalledIfHole),
+ B(ThrowSuperNotCalledIfTdzHole),
/* 139 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariable.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariable.golden
index d3dc3bec2ce..de258ec3dc9 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariable.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariable.golden
@@ -48,12 +48,12 @@ frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
- B(LdaTheHole),
+ B(LdaTdzHole),
B(Star0),
/* 44 S> */ B(LdaSmi), I8(20),
B(Star1),
B(Ldar), R(0),
- /* 48 E> */ B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ /* 48 E> */ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), RegCount8(0),
B(Star0),
B(LdaUndefined),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariableContextSlot.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
index 2122638abad..9ce0c645506 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
@@ -15,7 +15,7 @@ bytecode array length: 14
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 44 S> */ B(LdaSmi), I8(10),
/* 44 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -38,7 +38,7 @@ bytecode array length: 15
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 44 S> */ B(LdaSmi), I8(10),
/* 44 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -61,12 +61,12 @@ bytecode array length: 24
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 44 S> */ B(LdaSmi), I8(20),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(2),
- /* 47 E> */ B(ThrowReferenceErrorIfHole), U8(1:"x"),
+ /* 47 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"x"),
B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), RegCount8(0),
/* 44 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaUndefined),
@@ -89,7 +89,7 @@ bytecode array length: 21
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 44 S> */ B(LdaSmi), I8(10),
/* 44 E> */ B(StaCurrentContextSlotNoCell), C8(2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ContextVariables.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ContextVariables.golden
index afc21700892..0864076bd77 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ContextVariables.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ContextVariables.golden
@@ -106,13 +106,13 @@ bytecode array length: 28
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 56 S> */ B(LdaSmi), I8(1),
/* 56 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(CreateBlockContext), U8(1:SCOPE_INFO_TYPE),
B(PushContext), R(1),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 69 S> */ B(LdaSmi), I8(2),
/* 69 E> */ B(StaCurrentContextSlotNoCell), C8(2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ElideRedundantHoleChecks.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ElideRedundantHoleChecks.golden
index 6ea15389341..f8cf0382ba3 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ElideRedundantHoleChecks.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ElideRedundantHoleChecks.golden
@@ -22,7 +22,7 @@ parameter count: 2
bytecode array length: 6
bytecodes: [
/* 24 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 27 S> */ B(LdaUndefined),
/* 32 S> */ B(Return),
]
@@ -48,14 +48,14 @@ parameter count: 2
bytecode array length: 22
bytecodes: [
/* 24 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanFalse), U8(6),
/* 33 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 38 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star0),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 42 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 42 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 40 E> */ B(Add), R(0), EmbeddedFeedback(),
B(LdaUndefined),
/* 47 S> */ B(Return),
@@ -85,19 +85,19 @@ bytecodes: [
/* 24 S> */ B(Ldar), R(arg0),
B(JumpIfToBooleanFalse), U8(12),
/* 33 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 36 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(Jump), U8(10),
/* 48 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 51 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
/* 56 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 59 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 62 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(LdaUndefined),
/* 67 S> */ B(Return),
]
@@ -125,14 +125,14 @@ parameter count: 2
bytecode array length: 22
bytecodes: [
/* 31 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanFalse), U8(10),
/* 36 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 24 E> */ B(JumpLoop), U8(10), I8(0), FBV(0),
/* 41 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 44 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 49 S> */ B(Return),
]
@@ -159,13 +159,13 @@ parameter count: 2
bytecode array length: 20
bytecodes: [
/* 29 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 41 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(JumpIfToBooleanFalse), U8(6),
/* 24 E> */ B(JumpLoop), U8(10), I8(0), FBV(0),
/* 45 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 48 S> */ B(LdaUndefined),
/* 53 S> */ B(Return),
]
@@ -192,12 +192,12 @@ parameter count: 2
bytecode array length: 16
bytecodes: [
/* 29 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 32 S> */ B(Jump), U8(2),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 55 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 60 S> */ B(Return),
]
@@ -224,21 +224,21 @@ parameter count: 2
bytecode array length: 36
bytecodes: [
/* 29 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 32 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(JumpIfToBooleanFalse), U8(14),
/* 40 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(2:"w"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"w"),
/* 35 S> */ B(LdaImmutableCurrentContextSlot), C8(5),
- B(ThrowReferenceErrorIfHole), U8(3:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"z"),
/* 24 E> */ B(JumpLoop), U8(14), I8(0), FBV(0),
/* 45 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
/* 48 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
/* 51 S> */ B(LdaImmutableCurrentContextSlot), C8(5),
- B(ThrowReferenceErrorIfHole), U8(3:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"z"),
/* 54 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(2:"w"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"w"),
B(LdaUndefined),
/* 59 S> */ B(Return),
]
@@ -271,7 +271,7 @@ bytecodes: [
B(LdaZero),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 35 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 35 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(StaInArrayLiteral), R(0), R(1), FBV(2),
B(Ldar), R(0),
B(JumpIfUndefinedOrNull), U8(41),
@@ -285,18 +285,18 @@ bytecodes: [
B(JumpIfUndefined), U8(15),
/* 29 S> */ B(Star5),
B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(2:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"x"),
B(Ldar), R(5),
B(StaCurrentContextSlotNoCell), C8(2),
/* 41 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(3:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"z"),
B(ForInStep), R(4),
/* 24 E> */ B(JumpLoop), U8(26), I8(0), FBV(4),
/* 46 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(2:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"x"),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(3:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"z"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -329,7 +329,7 @@ bytecodes: [
B(LdaZero),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 35 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 35 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(StaInArrayLiteral), R(0), R(1), FBV(1),
B(GetIterator), R(0), FBV(3), FBV(5),
B(Star1),
@@ -353,11 +353,11 @@ bytecodes: [
B(LdaFalse),
/* 29 S> */ B(Star3),
B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(5:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(5:"x"),
B(Ldar), R(2),
B(StaCurrentContextSlotNoCell), C8(2),
/* 41 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(6:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(6:"z"),
/* 24 E> */ B(JumpLoop), U8(39), I8(0), FBV(15),
B(LdaSmi), I8(-1),
B(Star5),
@@ -394,10 +394,10 @@ bytecodes: [
B(Ldar), R(5),
B(ReThrow),
/* 46 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(5:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(5:"x"),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(6:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(6:"z"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -436,7 +436,7 @@ bytecodes: [
B(Mov), R(context), R(3),
B(Mov), R(context), R(4),
/* 30 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(Jump), U8(23),
B(Star5),
B(CreateCatchContext), R(5), U8(1:SCOPE_INFO_TYPE),
@@ -447,7 +447,7 @@ bytecodes: [
B(PushContext), R(5),
/* 47 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 50 S> */ B(LdaImmutableContextSlot), R(5), C8(5), U8(0),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(PopContext), R(5),
B(LdaSmi), I8(-1),
B(Star1),
@@ -460,7 +460,7 @@ bytecodes: [
B(SetPendingMessage),
B(Star2),
/* 65 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(3:"w"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"w"),
B(LdaZero),
B(TestReferenceEqual), R(0),
B(JumpIfFalse), U8(8),
@@ -469,11 +469,11 @@ bytecodes: [
B(Ldar), R(1),
B(ReThrow),
/* 70 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 73 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(4:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(4:"y"),
/* 76 S> */ B(LdaImmutableCurrentContextSlot), C8(5),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
/* 79 S> */ B(LdaUndefined),
/* 84 S> */ B(Return),
]
@@ -509,10 +509,10 @@ bytecodes: [
/* 30 E> */ B(GetNamedProperty), R(1), U8(1:"p"), FBV(1),
B(JumpIfNotUndefined), U8(6),
B(LdaImmutableCurrentContextSlot), C8(2),
- /* 34 E> */ B(ThrowReferenceErrorIfHole), U8(2:"x"),
+ /* 34 E> */ B(ThrowReferenceErrorIfTdzHole), U8(2:"x"),
B(Star0),
/* 50 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(2:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"x"),
B(LdaUndefined),
/* 55 S> */ B(Return),
]
@@ -540,19 +540,19 @@ parameter count: 2
bytecode array length: 29
bytecodes: [
/* 34 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanFalse), U8(12),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 39 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 39 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(JumpIfToBooleanFalse), U8(6),
B(LdaImmutableCurrentContextSlot), C8(4),
- /* 44 E> */ B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ /* 44 E> */ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(Star0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -580,19 +580,19 @@ parameter count: 2
bytecode array length: 29
bytecodes: [
/* 34 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanTrue), U8(12),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 39 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 39 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(JumpIfToBooleanTrue), U8(6),
B(LdaImmutableCurrentContextSlot), C8(4),
- /* 44 E> */ B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ /* 44 E> */ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(Star0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -620,21 +620,21 @@ parameter count: 2
bytecode array length: 33
bytecodes: [
/* 34 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfUndefinedOrNull), U8(4),
B(Jump), U8(14),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 39 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 39 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(JumpIfUndefinedOrNull), U8(4),
B(Jump), U8(6),
B(LdaImmutableCurrentContextSlot), C8(4),
- /* 44 E> */ B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ /* 44 E> */ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(Star0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -665,7 +665,7 @@ bytecodes: [
B(Star0),
B(JumpIfUndefinedOrNull), U8(29),
B(LdaImmutableCurrentContextSlot), C8(2),
- /* 35 E> */ B(ThrowReferenceErrorIfHole), U8(1:"x"),
+ /* 35 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"x"),
/* 34 E> */ B(GetKeyedProperty), R(0), FBV(1),
B(Star0),
B(JumpIfUndefinedOrNull), U8(19),
@@ -674,14 +674,14 @@ bytecodes: [
B(Star0),
B(JumpIfUndefinedOrNull), U8(11),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 45 E> */ B(ThrowReferenceErrorIfHole), U8(2:"y"),
+ /* 45 E> */ B(ThrowReferenceErrorIfTdzHole), U8(2:"y"),
/* 44 E> */ B(GetKeyedProperty), R(0), FBV(5),
B(Jump), U8(3),
B(LdaUndefined),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(1:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"x"),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(2:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"y"),
B(LdaUndefined),
/* 57 S> */ B(Return),
]
@@ -709,14 +709,14 @@ parameter count: 2
bytecode array length: 20
bytecodes: [
/* 24 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanFalse), U8(8),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 30 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 30 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 26 E> */ B(StaCurrentContextSlotNoCell), C8(2),
/* 33 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
/* 36 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 41 S> */ B(Return),
]
@@ -743,14 +743,14 @@ parameter count: 2
bytecode array length: 20
bytecodes: [
/* 24 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfToBooleanTrue), U8(8),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 30 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 30 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 26 E> */ B(StaCurrentContextSlotNoCell), C8(2),
/* 33 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
/* 36 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 41 S> */ B(Return),
]
@@ -777,15 +777,15 @@ parameter count: 2
bytecode array length: 22
bytecodes: [
/* 24 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(JumpIfUndefinedOrNull), U8(4),
B(Jump), U8(8),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 30 E> */ B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ /* 30 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 26 E> */ B(StaCurrentContextSlotNoCell), C8(2),
/* 33 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
/* 36 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 41 S> */ B(Return),
]
@@ -816,7 +816,7 @@ parameter count: 2
bytecode array length: 65
bytecodes: [
/* 24 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- /* 44 E> */ B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ /* 44 E> */ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(TestEqualStrict), R(arg0), EmbeddedFeedback(),
B(Mov), R(arg0), R(0),
B(JumpIfTrue), U8(11),
@@ -828,23 +828,23 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
/* 54 S> */ B(Jump), U8(24),
/* 61 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 64 S> */ B(Jump), U8(18),
/* 82 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 85 S> */ B(LdaImmutableCurrentContextSlot), C8(5),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
/* 99 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 102 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(3:"w"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"w"),
/* 107 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
/* 110 S> */ B(LdaImmutableCurrentContextSlot), C8(4),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 113 S> */ B(LdaImmutableCurrentContextSlot), C8(5),
- B(ThrowReferenceErrorIfHole), U8(2:"z"),
+ B(ThrowReferenceErrorIfTdzHole), U8(2:"z"),
/* 116 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(3:"w"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"w"),
B(LdaUndefined),
/* 121 S> */ B(Return),
]
@@ -877,15 +877,15 @@ parameter count: 2
bytecode array length: 22
bytecodes: [
/* 33 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 38 S> */ B(Ldar), R(arg0),
B(JumpIfToBooleanFalse), U8(4),
/* 45 S> */ B(Jump), U8(6),
/* 58 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 63 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 66 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaUndefined),
/* 71 S> */ B(Return),
]
@@ -915,9 +915,9 @@ parameter count: 2
bytecode array length: 12
bytecodes: [
/* 28 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 33 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
/* 38 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
/* 41 S> */ B(LdaUndefined),
/* 46 S> */ B(Return),
@@ -948,7 +948,7 @@ bytecode array length: 28
bytecodes: [
B(Mov), R(context), R(0),
/* 32 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(Jump), U8(15),
B(Star1),
B(CreateCatchContext), R(1), U8(1:SCOPE_INFO_TYPE),
@@ -959,7 +959,7 @@ bytecodes: [
B(PushContext), R(1),
B(PopContext), R(1),
/* 50 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(LdaUndefined),
/* 55 S> */ B(Return),
]
@@ -990,7 +990,7 @@ bytecode array length: 30
bytecodes: [
B(Mov), R(context), R(0),
/* 32 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(Jump), U8(21),
B(Star1),
B(CreateCatchContext), R(1), U8(1:SCOPE_INFO_TYPE),
@@ -1000,7 +1000,7 @@ bytecodes: [
B(Ldar), R(0),
B(PushContext), R(1),
/* 49 S> */ B(LdaImmutableContextSlot), R(1), C8(2), U8(0),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(PopContext), R(1),
/* 54 S> */ B(LdaUndefined),
/* 59 S> */ B(Return),
@@ -1034,7 +1034,7 @@ bytecodes: [
B(Star2),
B(Mov), R(context), R(3),
/* 32 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(LdaSmi), I8(-1),
B(Star1),
B(Star0),
@@ -1046,7 +1046,7 @@ bytecodes: [
B(SetPendingMessage),
B(Star2),
/* 47 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
- B(ThrowReferenceErrorIfHole), U8(1:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(1:"y"),
B(LdaZero),
B(TestReferenceEqual), R(0),
B(JumpIfFalse), U8(8),
@@ -1055,7 +1055,7 @@ bytecodes: [
B(Ldar), R(1),
B(ReThrow),
/* 52 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 55 S> */ B(LdaUndefined),
/* 60 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ForOfLoop.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ForOfLoop.golden
index 8429f497162..ee6263cdeb1 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ForOfLoop.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ForOfLoop.golden
@@ -114,7 +114,7 @@ bytecodes: [
B(StaCurrentContextSlotNoCell), C8(5),
B(CreateBlockContext), U8(1:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 34 S> */ B(LdaContextSlotNoCell), R(3), C8(4), U8(0),
B(Star6),
@@ -142,7 +142,7 @@ bytecodes: [
B(Mov), R(6), R(0),
B(CreateBlockContext), U8(5:SCOPE_INFO_TYPE),
B(PushContext), R(12),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 29 S> */ B(Ldar), R(0),
/* 29 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -254,7 +254,7 @@ bytecodes: [
B(Mov), R(4), R(0),
B(CreateBlockContext), U8(3:SCOPE_INFO_TYPE),
B(PushContext), R(10),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 29 S> */ B(Ldar), R(0),
/* 29 E> */ B(StaCurrentContextSlotNoCell), C8(2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/HoleCheckElision.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/HoleCheckElision.golden
index 26432d72bea..c9972196f5d 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/HoleCheckElision.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/HoleCheckElision.golden
@@ -34,7 +34,7 @@ parameter count: 1
bytecode array length: 5
bytecodes: [
/* 55 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 64 S> */ B(Return),
]
constant pool: [
@@ -71,7 +71,7 @@ parameter count: 1
bytecode array length: 5
bytecodes: [
/* 57 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"y"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"y"),
/* 66 S> */ B(Return),
]
constant pool: [
@@ -176,7 +176,7 @@ parameter count: 1
bytecode array length: 5
bytecodes: [
/* 91 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 100 S> */ B(Return),
]
constant pool: [
@@ -200,7 +200,7 @@ parameter count: 1
bytecode array length: 7
bytecodes: [
/* 127 S> */ B(LdaImmutableContextSlot), R(context), C8(2), U8(1),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 136 S> */ B(Return),
]
constant pool: [
@@ -242,7 +242,7 @@ parameter count: 1
bytecode array length: 7
bytecodes: [
/* 52 S> */ B(LdaImmutableContextSlot), R(context), C8(2), U8(1),
- B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
/* 61 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariable.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariable.golden
index 146d8ba89fd..b66221f89e4 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariable.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariable.golden
@@ -48,12 +48,12 @@ frame size: 2
parameter count: 1
bytecode array length: 14
bytecodes: [
- B(LdaTheHole),
+ B(LdaTdzHole),
B(Star0),
/* 42 S> */ B(LdaSmi), I8(20),
B(Star1),
B(Ldar), R(0),
- /* 45 E> */ B(ThrowReferenceErrorIfHole), U8(0:"x"),
+ /* 45 E> */ B(ThrowReferenceErrorIfTdzHole), U8(0:"x"),
B(Mov), R(1), R(0),
B(LdaUndefined),
/* 52 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariableContextSlot.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariableContextSlot.golden
index e44dcdb8a3a..a0facb3c3ab 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariableContextSlot.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/LetVariableContextSlot.golden
@@ -15,7 +15,7 @@ bytecode array length: 14
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 S> */ B(LdaSmi), I8(10),
/* 42 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -38,7 +38,7 @@ bytecode array length: 15
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 S> */ B(LdaSmi), I8(10),
/* 42 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -61,12 +61,12 @@ bytecode array length: 23
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 S> */ B(LdaSmi), I8(20),
B(Star1),
B(LdaCurrentContextSlotNoCell), C8(2),
- /* 45 E> */ B(ThrowReferenceErrorIfHole), U8(1:"x"),
+ /* 45 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"x"),
B(Ldar), R(1),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -90,7 +90,7 @@ bytecode array length: 18
bytecodes: [
/* 30 E> */ B(CreateFunctionContext), U8(0:SCOPE_INFO_TYPE), U8(1),
B(PushContext), R(0),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 42 S> */ B(LdaSmi), I8(10),
/* 42 E> */ B(StaCurrentContextSlotNoCell), C8(2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
index 1cf5bf686fe..5f885b398b6 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
@@ -98,7 +98,7 @@ bytecodes: [
B(Ldar), R(2),
B(Return),
/* 32 S> */ B(LdaModuleVariable), I8(-1), U8(0),
- B(ThrowReferenceErrorIfHole), U8(3:"goo"),
+ B(ThrowReferenceErrorIfTdzHole), U8(3:"goo"),
B(Star2),
B(LdaSmi), I8(42),
B(Star3),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ObjectLiterals.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ObjectLiterals.golden
index ee23185c716..c972f099dde 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ObjectLiterals.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ObjectLiterals.golden
@@ -51,7 +51,7 @@ bytecodes: [
/* 45 S> */ B(CreateObjectLiteral), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star1),
B(Ldar), R(0),
- /* 75 E> */ B(DefineNamedOwnProperty), R(1), U8(1:"val"), FBV(1),
+ /* 75 E> */ B(DefineNamedOwnPropertyInLiteral), R(1), U8(1:"val"), FBV(1),
B(Ldar), R(1),
/* 79 S> */ B(Return),
]
@@ -76,7 +76,7 @@ bytecodes: [
B(Star1),
B(Ldar), R(0),
/* 69 E> */ B(AddSmi), I8(1), EmbeddedFeedback(),
- B(DefineNamedOwnProperty), R(1), U8(1:"val"), FBV(1),
+ B(DefineNamedOwnPropertyInLiteral), R(1), U8(1:"val"), FBV(1),
B(Ldar), R(1),
/* 75 S> */ B(Return),
]
@@ -98,7 +98,7 @@ bytecodes: [
/* 34 S> */ B(CreateObjectLiteral), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star0),
/* 49 E> */ B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
- B(DefineNamedOwnProperty), R(0), U8(2:"func"), FBV(1),
+ B(DefineNamedOwnPropertyInLiteral), R(0), U8(2:"func"), FBV(1),
B(Ldar), R(0),
/* 66 S> */ B(Return),
]
@@ -121,7 +121,7 @@ bytecodes: [
/* 34 S> */ B(CreateObjectLiteral), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star0),
/* 43 E> */ B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
- B(DefineNamedOwnProperty), R(0), U8(2:"func"), FBV(1),
+ B(DefineNamedOwnPropertyInLiteral), R(0), U8(2:"func"), FBV(1),
B(Ldar), R(0),
/* 67 S> */ B(Return),
]
@@ -309,7 +309,7 @@ bytecodes: [
/* 50 S> */ B(CreateObjectLiteral), U8(1:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star1),
B(Ldar), R(0),
- /* 64 E> */ B(DefineNamedOwnProperty), R(1), U8(2:"val"), FBV(1),
+ /* 64 E> */ B(DefineNamedOwnPropertyInLiteral), R(1), U8(2:"val"), FBV(1),
B(Ldar), R(0),
/* 68 E> */ B(ToName),
B(Star2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden
index 779c80e1a27..e52f9bb33d6 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden
@@ -24,22 +24,22 @@ bytecodes: [
B(Star3),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(3), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star3),
+ B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(5:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star3),
- B(CreateClosure), U8(5:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 101 S> */ B(Return),
]
@@ -72,22 +72,22 @@ bytecodes: [
B(Star3),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(3), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star3),
+ B(LdaNull),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star3),
- B(LdaNull),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 81 S> */ B(Return),
]
@@ -119,22 +119,22 @@ bytecodes: [
B(Star3),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(3), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
+ B(LdaNull),
+ B(Star3),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(LdaNull),
- B(Star3),
- B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 74 S> */ B(Return),
]
@@ -172,43 +172,43 @@ bytecodes: [
B(Star4),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(4), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star4),
+ B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
+ B(Star5),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star6),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(5:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
B(Star3),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), RegCount8(3),
- B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star4),
- B(CreateClosure), U8(5:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
- B(Star5),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(2),
- B(Mov), R(3), R(0),
+ B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6:SCOPE_INFO_TYPE),
B(PushContext), R(2),
B(LdaConstant), U8(8:"E"),
B(Star4),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(4), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
- /* 118 E> */ B(CreateClosure), U8(9:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
+ B(CreateClosure), U8(9:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
+ B(Star4),
+ B(CreateClosure), U8(10:SHARED_FUNCTION_INFO_TYPE), FBV(4), Flag8(0x2),
+ B(Star5),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
+ /* 118 E> */ B(CreateClosure), U8(11:SHARED_FUNCTION_INFO_TYPE), FBV(5), Flag8(0x2),
B(Star3),
B(LdaConstant), U8(7:CLASS_BOILERPLATE_TYPE),
B(Star4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), RegCount8(3),
- B(CreateClosure), U8(10:SHARED_FUNCTION_INFO_TYPE), FBV(4), Flag8(0x2),
- B(Star4),
- B(CreateClosure), U8(11:SHARED_FUNCTION_INFO_TYPE), FBV(5), Flag8(0x2),
- B(Star5),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(2),
- B(Mov), R(3), R(1),
+ B(Mov), R(5), R(1),
B(LdaUndefined),
/* 175 S> */ B(Return),
]
@@ -241,7 +241,7 @@ snippet: "
"
frame size: 8
parameter count: 1
-bytecode array length: 99
+bytecode array length: 95
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(2),
@@ -263,7 +263,13 @@ bytecodes: [
B(Star4),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(4), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
- /* 77 E> */ B(CreateClosure), U8(7:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
+ B(CreateClosure), U8(7:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
+ B(Star4),
+ B(LdaNull),
+ B(Star5),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
+ /* 77 E> */ B(CreateClosure), U8(8:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
B(Star3),
B(LdaConstant), U8(5:CLASS_BOILERPLATE_TYPE),
B(Star4),
@@ -273,16 +279,9 @@ bytecodes: [
B(StaCurrentContextSlotNoCell), C8(4),
B(Ldar), R(5),
B(StaCurrentContextSlotNoCell), C8(5),
- B(CreateClosure), U8(8:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
- B(Star4),
- B(LdaNull),
- B(Star5),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(2),
- B(Mov), R(3), R(1),
- /* 122 S> */ B(Ldar), R(1),
- /* 122 E> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
+ B(Star1),
+ /* 122 S> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
B(LdaUndefined),
/* 133 S> */ B(Return),
]
@@ -312,7 +311,7 @@ snippet: "
"
frame size: 8
parameter count: 1
-bytecode array length: 99
+bytecode array length: 95
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(2),
@@ -334,7 +333,13 @@ bytecodes: [
B(Star4),
B(CallRuntime), U16(Runtime::kCreatePrivateBrandSymbol), R(4), RegCount8(1),
B(StaCurrentContextSlotNoCell), C8(3),
- /* 80 E> */ B(CreateClosure), U8(7:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
+ B(LdaNull),
+ B(Star4),
+ B(CreateClosure), U8(7:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
+ B(Star5),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
+ /* 80 E> */ B(CreateClosure), U8(8:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
B(Star3),
B(LdaConstant), U8(5:CLASS_BOILERPLATE_TYPE),
B(Star4),
@@ -344,16 +349,9 @@ bytecodes: [
B(StaCurrentContextSlotNoCell), C8(4),
B(Ldar), R(5),
B(StaCurrentContextSlotNoCell), C8(5),
- B(LdaNull),
- B(Star4),
- B(CreateClosure), U8(8:SHARED_FUNCTION_INFO_TYPE), FBV(3), Flag8(0x2),
- B(Star5),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(2),
- B(Mov), R(3), R(1),
- /* 126 S> */ B(Ldar), R(1),
- /* 126 E> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
+ B(Star1),
+ /* 126 S> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
B(LdaUndefined),
/* 137 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateMethodAccess.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateMethodAccess.golden
index 78a0b199923..7d9b1b73cda 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateMethodAccess.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateMethodAccess.golden
@@ -172,7 +172,7 @@ bytecodes: [
/* 89 E> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Ldar), R(1),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaImmutableContextSlot), R(context), C8(3), U8(1),
@@ -224,7 +224,7 @@ bytecodes: [
/* 88 E> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Ldar), R(1),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaImmutableContextSlot), R(context), C8(3), U8(1),
@@ -275,7 +275,7 @@ bytecodes: [
/* 88 E> */ B(Construct), R(1), R(0), RegCount8(0), FBV(0),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(2),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Ldar), R(1),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaImmutableContextSlot), R(context), C8(3), U8(1),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/PublicClassFields.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/PublicClassFields.golden
index 71244c73d27..5db865ffb6c 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/PublicClassFields.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/PublicClassFields.golden
@@ -27,7 +27,7 @@ bytecode array length: 102
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star6),
@@ -46,7 +46,7 @@ bytecodes: [
B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6:SCOPE_INFO_TYPE),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star6),
@@ -121,7 +121,7 @@ bytecode array length: 196
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star11),
@@ -147,7 +147,7 @@ bytecodes: [
B(Mov), R(6), R(0),
/* 38 E> */ B(CreateBlockContext), U8(8:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star11),
@@ -175,7 +175,7 @@ bytecodes: [
B(Mov), R(6), R(1),
/* 90 E> */ B(CreateBlockContext), U8(15:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 236 E> */ B(CreateClosure), U8(17:SHARED_FUNCTION_INFO_TYPE), FBV(7), Flag8(0x2),
B(Star4),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/SetPrototypePropertiesOptimization.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/SetPrototypePropertiesOptimization.golden
index e5f82c00579..4cf494b89e4 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/SetPrototypePropertiesOptimization.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/SetPrototypePropertiesOptimization.golden
@@ -53,7 +53,7 @@ parameter count: 1
bytecode array length: 9
bytecodes: [
B(LdaImmutableCurrentContextSlot), C8(2),
- /* 109 E> */ B(ThrowReferenceErrorIfHole), U8(1:"MyClass"),
+ /* 109 E> */ B(ThrowReferenceErrorIfTdzHole), U8(1:"MyClass"),
B(SetPrototypeProperties), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0),
B(LdaUndefined),
/* 245 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
index b7103eabf9a..e0e42d1bd62 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
@@ -56,7 +56,7 @@ bytecodes: [
B(StaCurrentContextSlotNoCell), C8(4),
B(CreateBlockContext), U8(1:SCOPE_INFO_TYPE),
B(PushContext), R(5),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
/* 30 S> */ B(LdaZero),
/* 30 E> */ B(StaCurrentContextSlotNoCell), C8(2),
@@ -66,7 +66,7 @@ bytecodes: [
B(Star1),
/* 59 E> */ B(CreateBlockContext), U8(2:SCOPE_INFO_TYPE),
B(PushContext), R(6),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(Ldar), R(0),
B(StaCurrentContextSlotNoCell), C8(2),
@@ -152,7 +152,7 @@ bytecodes: [
B(Star1),
/* 78 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(4),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
B(Ldar), R(0),
B(StaCurrentContextSlotNoCell), C8(2),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticClassFields.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticClassFields.golden
index 282a7cb25ba..171412bd790 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticClassFields.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticClassFields.golden
@@ -31,9 +31,9 @@ bytecode array length: 164
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(3),
B(LdaTheHole),
B(Star6),
@@ -63,9 +63,9 @@ bytecodes: [
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(9:SCOPE_INFO_TYPE),
B(PushContext), R(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(3),
B(LdaTheHole),
B(Star6),
@@ -161,9 +161,9 @@ bytecode array length: 295
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(3),
B(LdaTheHole),
B(Star11),
@@ -200,9 +200,9 @@ bytecodes: [
B(Mov), R(4), R(0),
/* 38 E> */ B(CreateBlockContext), U8(11:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(3),
B(LdaTheHole),
B(Star11),
@@ -241,9 +241,9 @@ bytecodes: [
B(Mov), R(4), R(1),
/* 122 E> */ B(CreateBlockContext), U8(19:SCOPE_INFO_TYPE),
B(PushContext), R(3),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(2),
- B(LdaTheHole),
+ B(LdaTdzHole),
B(StaCurrentContextSlotNoCell), C8(3),
/* 313 E> */ B(CreateClosure), U8(21:SHARED_FUNCTION_INFO_TYPE), FBV(9), Flag8(0x2),
B(Star4),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
index 5b40068df4e..7bc4e1bfda0 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
@@ -20,7 +20,7 @@ frame size: 4
parameter count: 1
bytecode array length: 32
bytecodes: [
- /* 56 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
+ /* 56 S> */ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(16),
@@ -57,7 +57,7 @@ bytecode array length: 40
bytecodes: [
/* 56 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
- B(LdaImmutableCurrentContextSlot), C8(3),
+ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -95,7 +95,7 @@ frame size: 3
parameter count: 1
bytecode array length: 37
bytecodes: [
- /* 56 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
+ /* 56 S> */ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -141,7 +141,7 @@ bytecode array length: 127
bytecodes: [
/* 90 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
- B(LdaImmutableCurrentContextSlot), C8(3),
+ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -163,7 +163,7 @@ bytecodes: [
B(Star1),
B(LdaSmi), I8(1),
B(Star2),
- B(LdaImmutableCurrentContextSlot), C8(3),
+ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -178,7 +178,7 @@ bytecodes: [
B(CallProperty1), R(3), R(0), R(2), FBV(4),
/* 122 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
- B(LdaImmutableCurrentContextSlot), C8(3),
+ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -212,7 +212,7 @@ frame size: 3
parameter count: 1
bytecode array length: 37
bytecodes: [
- /* 60 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
+ /* 60 S> */ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -249,7 +249,7 @@ frame size: 3
parameter count: 1
bytecode array length: 37
bytecodes: [
- /* 53 S> */ B(LdaImmutableCurrentContextSlot), C8(3),
+ /* 53 S> */ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
@@ -288,7 +288,7 @@ bytecode array length: 40
bytecodes: [
/* 60 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
- B(LdaImmutableCurrentContextSlot), C8(3),
+ B(LdaCurrentContextSlotNoCell), C8(3),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden
index c4926a54d72..14e2e51478e 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden
@@ -57,22 +57,22 @@ bytecode array length: 43
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(1),
+ B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star3),
+ B(LdaNull),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star3),
- B(LdaNull),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 88 S> */ B(Return),
]
@@ -99,22 +99,22 @@ bytecode array length: 43
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(1),
+ B(LdaNull),
+ B(Star3),
+ B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(LdaNull),
- B(Star3),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 81 S> */ B(Return),
]
@@ -142,22 +142,22 @@ bytecode array length: 46
bytecodes: [
/* 30 E> */ B(CreateBlockContext), U8(0:SCOPE_INFO_TYPE),
B(PushContext), R(1),
+ B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(Star3),
+ B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
+ B(Star4),
+ B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
+ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaTheHole),
B(Star5),
- B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
+ B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
B(Star2),
B(LdaConstant), U8(1:CLASS_BOILERPLATE_TYPE),
B(Star3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), RegCount8(3),
- B(CreateClosure), U8(3:SHARED_FUNCTION_INFO_TYPE), FBV(1), Flag8(0x2),
- B(Star3),
- B(CreateClosure), U8(4:SHARED_FUNCTION_INFO_TYPE), FBV(2), Flag8(0x2),
- B(Star4),
- B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(3), RegCount8(2),
- B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(1),
- B(Mov), R(2), R(0),
+ B(Mov), R(4), R(0),
B(LdaUndefined),
/* 115 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
index 6d7b8b99a11..8c385060c83 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
@@ -75,10 +75,10 @@ bytecodes: [
/* 140 E> */ B(ConstructWithSpread), R(6), R(7), RegCount8(2), FBV(0),
B(Star6),
B(Ldar), R(this),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Mov), R(6), R(this),
B(Ldar), R(this),
- B(ThrowSuperNotCalledIfHole),
+ B(ThrowSuperNotCalledIfTdzHole),
/* 159 S> */ B(Return),
]
constant pool: [
@@ -139,10 +139,10 @@ bytecodes: [
B(CallJSRuntime), U8(%reflect_construct), R(6), RegCount8(3),
B(Star6),
B(Ldar), R(this),
- B(ThrowSuperAlreadyCalledIfNotHole),
+ B(ThrowSuperAlreadyCalledIfNotTdzHole),
B(Mov), R(6), R(this),
B(Ldar), R(this),
- B(ThrowSuperNotCalledIfHole),
+ B(ThrowSuperNotCalledIfTdzHole),
/* 162 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
index 922ff3d25fd..a241697e852 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
@@ -21,7 +21,7 @@ bytecodes: [
/* 8 S> */ B(CreateObjectLiteral), U8(1:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star0),
/* 16 E> */ B(CreateClosure), U8(2:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x0),
- B(DefineNamedOwnProperty), R(0), U8(3:"func"), FBV(1),
+ B(DefineNamedOwnPropertyInLiteral), R(0), U8(3:"func"), FBV(1),
B(Ldar), R(0),
/* 8 E> */ B(StaGlobal), U8(4:"a"), FBV(3),
B(LdaUndefined),
diff --git a/deps/v8/test/unittests/maglev/hamt-unittest.cc b/deps/v8/test/unittests/maglev/hamt-unittest.cc
index 457fac9ba5d..64a64b89937 100644
--- a/deps/v8/test/unittests/maglev/hamt-unittest.cc
+++ b/deps/v8/test/unittests/maglev/hamt-unittest.cc
@@ -4,6 +4,8 @@
#include "src/maglev/hamt.h"
+#include <algorithm>
+
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,6 +34,10 @@ class HAMTTest : public TestWithZone {
const int* FindWithHash(IntHAMT& hamt, int key, size_t hash) const {
return hamt.FindHelper(hamt.root_, key, hash, 0);
}
+
+ bool SameRoot(const IntHAMT& a, const IntHAMT& b) const {
+ return a.root_ == b.root_;
+ }
};
TEST_F(HAMTTest, EmptyState) {
@@ -231,6 +237,134 @@ TEST_F(HAMTTest, MergeIntoIsLeftJoin) {
EXPECT_EQ(result.find(3), nullptr);
}
+TEST_F(HAMTTest, MergeIntoWithoutChangesDoesNotAllocate) {
+ IntHAMT hA;
+ IntHAMT hB;
+ for (int i = 0; i < 200; i++) {
+ hA = hA.insert(zone(), i, i);
+ // {hB} holds smaller values, so a max-merge into {hA} changes nothing.
+ hB = hB.insert(zone(), i, i - 1);
+ }
+
+ size_t allocated_before = zone()->allocation_size();
+ auto max = [](int a, int b) { return std::max(a, b); };
+ IntHAMT result = hA.merge_into(zone(), hB, max);
+
+ EXPECT_EQ(zone()->allocation_size(), allocated_before);
+ EXPECT_TRUE(SameRoot(result, hA));
+ EXPECT_EQ(ToMap(result), ToMap(hA));
+}
+
+TEST_F(HAMTTest, MergeIntoWithoutChangesDoesNotAllocateWithCollisions) {
+ IntHAMT hA;
+ IntHAMT hB;
+ // Same hash for every key, so everything ends up in one collision chain.
+ for (int i = 0; i < 10; i++) {
+ hA = InsertWithHash(hA, i, i, 0x1234);
+ hB = InsertWithHash(hB, i, i - 1, 0x1234);
+ }
+
+ size_t allocated_before = zone()->allocation_size();
+ auto max = [](int a, int b) { return std::max(a, b); };
+ IntHAMT result = hA.merge_into(zone(), hB, max);
+
+ EXPECT_EQ(zone()->allocation_size(), allocated_before);
+ EXPECT_TRUE(SameRoot(result, hA));
+}
+
+TEST_F(HAMTTest, MergeIntoWithOneChangeIsAPathCopy) {
+ IntHAMT hA;
+ IntHAMT hB;
+ for (int i = 0; i < 200; i++) {
+ hA = hA.insert(zone(), i, i);
+ hB = hB.insert(zone(), i, i - 1);
+ }
+ // A single key now wins the merge.
+ hB = hB.insert(zone(), 42, 4242);
+
+ size_t allocated_before = zone()->allocation_size();
+ auto max = [](int a, int b) { return std::max(a, b); };
+ IntHAMT result = hA.merge_into(zone(), hB, max);
+ size_t allocated = zone()->allocation_size() - allocated_before;
+
+ EXPECT_FALSE(SameRoot(result, hA));
+ ASSERT_NE(result.find(42), nullptr);
+ EXPECT_EQ(*result.find(42), 4242);
+ for (int i = 0; i < 200; i++) {
+ if (i == 42) continue;
+ ASSERT_NE(result.find(i), nullptr);
+ EXPECT_EQ(*result.find(i), i);
+ }
+ // Only the path to the changed key is rebuilt, not the whole map. The bound
+ // is deliberately loose; the point is that it does not scale with the size
+ // of the map.
+ EXPECT_LT(allocated, 1024u);
+}
+
+class HAMTMismatchedShapesTest : public HAMTTest {
+ protected:
+ // Hashes are picked so that key 1 is a lone leaf in {small} but shares a
+ // level-1 branch with key 3 in {big}:
+ // 0x01: level 0 bit 1, level 1 bit 0
+ // 0x21: level 0 bit 1, level 1 bit 1
+ // 0x02: level 0 bit 2
+ //
+ // small: root{1: Leaf(1), 2: Leaf(2)}
+ // big: root{1: Branch{0: Leaf(1), 1: Leaf(3)}, 2: Leaf(2)}
+ static constexpr size_t kHash1 = 0x01;
+ static constexpr size_t kHash2 = 0x02;
+ static constexpr size_t kHash3 = 0x21;
+
+ IntHAMT MakeSmall(int v1, int v2) {
+ IntHAMT h;
+ h = InsertWithHash(h, 1, v1, kHash1);
+ return InsertWithHash(h, 2, v2, kHash2);
+ }
+ IntHAMT MakeBig(int v1, int v2, int v3) {
+ IntHAMT h;
+ h = InsertWithHash(h, 1, v1, kHash1);
+ h = InsertWithHash(h, 3, v3, kHash3);
+ return InsertWithHash(h, 2, v2, kHash2);
+ }
+
+ static int Max(int a, int b) { return std::max(a, b); }
+ static int Min(int a, int b) { return std::min(a, b); }
+};
+
+TEST_F(HAMTMismatchedShapesTest, WithoutChangesDoesNotAllocate) {
+ IntHAMT small = MakeSmall(10, 20);
+ IntHAMT big = MakeBig(5, 5, 5);
+
+ // Leaf(1) x Branch{1, 3}: MergeIntoLeaf.
+ size_t allocated_before = zone()->allocation_size();
+ IntHAMT result = small.merge_into(zone(), big, Max);
+ EXPECT_EQ(zone()->allocation_size(), allocated_before);
+ EXPECT_TRUE(SameRoot(result, small));
+
+ // Branch{1, 3} x Leaf(1): MergeIntoBranch.
+ allocated_before = zone()->allocation_size();
+ result = big.merge_into(zone(), small, Min);
+ EXPECT_EQ(zone()->allocation_size(), allocated_before);
+ EXPECT_TRUE(SameRoot(result, big));
+}
+
+TEST_F(HAMTMismatchedShapesTest, WithChanges) {
+ IntHAMT small = MakeSmall(10, 20);
+ IntHAMT big = MakeBig(50, 5, 5);
+
+ // Leaf(1) x Branch{1, 3}: only key 1 changes; key 3 is not in {small}.
+ IntHAMT result = small.merge_into(zone(), big, Max);
+ EXPECT_FALSE(SameRoot(result, small));
+ EXPECT_EQ(ToMap(result), (std::map<int, int>{{1, 50}, {2, 20}}));
+ EXPECT_EQ(ToMap(small), (std::map<int, int>{{1, 10}, {2, 20}}));
+
+ // Branch{1, 3} x Leaf(1): only key 1 changes; key 3 keeps its value.
+ result = big.merge_into(zone(), small, Min);
+ EXPECT_FALSE(SameRoot(result, big));
+ EXPECT_EQ(ToMap(result), (std::map<int, int>{{1, 10}, {2, 5}, {3, 5}}));
+ EXPECT_EQ(ToMap(big), (std::map<int, int>{{1, 50}, {2, 5}, {3, 5}}));
+}
+
TEST_F(HAMTTest, IteratorTraversal) {
IntHAMT hamt;
hamt = hamt.insert(zone(), 10, 1);
diff --git a/deps/v8/test/unittests/maglev/maglev-graph-builder-unittest.cc b/deps/v8/test/unittests/maglev/maglev-graph-builder-unittest.cc
index 23a99256d2e..caeb4f984b9 100644
--- a/deps/v8/test/unittests/maglev/maglev-graph-builder-unittest.cc
+++ b/deps/v8/test/unittests/maglev/maglev-graph-builder-unittest.cc
@@ -8,8 +8,10 @@
#include "src/maglev/maglev-compilation-info.h"
#include "src/maglev/maglev-compiler.h"
+#include "src/maglev/maglev-graph-labeller.h"
#include "src/maglev/maglev-ir-inl.h"
#include "src/maglev/maglev-ir.h"
+#include "test/common/flag-utils.h"
#include "test/unittests/maglev/maglev-test.h"
namespace v8 {
@@ -18,6 +20,55 @@ namespace maglev {
class MaglevGraphBuilderTest : public TestWithNativeContextAndZone {};
+TEST_F(MaglevGraphBuilderTest, LoopEffectEpochComparison) {
+ FlagScope<bool> allow_natives_syntax(&v8_flags.allow_natives_syntax, true);
+ FlagScope<bool> non_eager_inlining(&v8_flags.maglev_non_eager_inlining, true);
+ FlagScope<bool> optimistic_loops(&v8_flags.maglev_optimistic_peeled_loops,
+ true);
+ for (bool peeling : {false, true}) {
+ FlagScope<bool> loop_peeling(&v8_flags.maglev_loop_peeling, peeling);
+ for (bool has_effects : {false, true}) {
+ HandleScope scope(isolate());
+ std::string script = R"(
+ function f(object, n) {
+ let result = 0;
+ for (let i = 0; i < n; ++i) {
+ result += i;
+ )";
+ if (has_effects) script += "object.x = i;";
+ script += R"(
+ }
+ return result;
+ }
+ %PrepareFunctionForOptimization(f);
+ f({x: 0}, 10);
+ (f)
+ )";
+ Handle<JSFunction> function = RunJS<JSFunction>(script.c_str());
+ auto info = MaglevCompilationInfo::New(isolate(), function,
+ BytecodeOffset::None());
+ info->set_graph_labeller(new MaglevGraphLabeller());
+ MaglevGraphLabellerScope graph_labeller_scope(info->graph_labeller());
+ Graph* graph = Graph::New(info.get());
+ compiler::CurrentHeapBrokerScope current_broker(info->broker());
+ MaglevGraphBuilder graph_builder(isolate()->AsLocalIsolate(),
+ info->toplevel_compilation_unit(),
+ graph);
+ PersistentHandlesScope persistent_scope(isolate());
+ ASSERT_TRUE(graph_builder.Build());
+ int loop_count = 0;
+ for (BasicBlock* block : graph->blocks()) {
+ if (!block->is_loop()) continue;
+ ++loop_count;
+ EXPECT_EQ(has_effects,
+ block->state()->AsLoopHeader()->loop_has_effects());
+ }
+ EXPECT_EQ(1, loop_count);
+ persistent_scope.Detach();
+ }
+ }
+}
+
template <typename T>
static T* getUniqueNode(Graph* graph) {
T* target = nullptr;
diff --git a/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc b/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc
index d552380a860..df1ad514d80 100644
--- a/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc
+++ b/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc
@@ -159,6 +159,35 @@ TEST_F(MaglevGraphProcessorTest, GraphBackwardMultiProcessorOrder) {
persistent_scope.Detach();
}
+TEST_F(MaglevGraphProcessorTest, LoopHeaderAvailableExpressions) {
+ RunSubgraphTest([&](MaglevReducer<MaglevGraphOptimizer>& reducer,
+ BasicBlock* block) {
+ ValueNode* object = reducer.GetRootConstant(RootIndex::kUndefinedValue);
+ auto* load =
+ reducer.AddNewNodeNoInputConversion<LoadDataViewByteLength>({object});
+ ValueNode* value = reducer.GetFloat64Constant(1.0);
+ auto* pure =
+ reducer.AddNewNodeNoInputConversion<Float64Add>({value, value});
+ std::array<ValueNode*, 1> load_inputs{object};
+ std::array<ValueNode*, 2> pure_inputs{value, value};
+ KnownNodeAspects backedge(zone());
+ for (bool loop_has_effects : {false, true}) {
+ for (bool stale : {false, true}) {
+ KnownNodeAspects forward(zone());
+ forward.AddExpression(1, load);
+ forward.AddExpression(2, pure);
+ if (stale) forward.increment_effect_epoch();
+ forward.MergeForLoop(backedge, zone(), nullptr, loop_has_effects);
+ EXPECT_EQ(
+ !loop_has_effects && !stale ? load : nullptr,
+ forward.FindExpression<LoadDataViewByteLength>(1, load_inputs));
+ EXPECT_EQ(pure, forward.FindExpression<Float64Add>(2, pure_inputs));
+ }
+ }
+ reducer.FlushNodesToBlock();
+ });
+}
+
TEST_F(MaglevGraphProcessorTest, SubgraphBufferStashingNodesFromBefore) {
RunSubgraphTest(
[](MaglevReducer<MaglevGraphOptimizer>& reducer, BasicBlock* block) {
diff --git a/deps/v8/test/unittests/objects/feedback-vector-unittest.cc b/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
index 84081da5f1e..2787c864139 100644
--- a/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
+++ b/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
@@ -468,19 +468,6 @@ TEST_F(FeedbackVectorTest, VectorLoadICStates) {
nexus.ExtractMaps(&maps);
CHECK_EQ(4, maps.size());
- // Fill up to max_valid_polymorphic_map_count.
- TryRunJS(
- "for (let i = 4; i < 10; ++i) {"
- " let obj = { foo: 2 };"
- " obj['p' + i] = i;"
- " f(obj);"
- "}");
- CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
- maps.clear();
- nexus.ExtractMaps(&maps);
- CHECK_EQ(static_cast<size_t>(v8_flags.max_valid_polymorphic_map_count),
- maps.size());
-
// Finally driven megamorphic.
TryRunJS("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })");
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
diff --git a/deps/v8/test/unittests/parser/ast-value-unittest.cc b/deps/v8/test/unittests/parser/ast-value-unittest.cc
index 91efc9e42a9..57441b4179d 100644
--- a/deps/v8/test/unittests/parser/ast-value-unittest.cc
+++ b/deps/v8/test/unittests/parser/ast-value-unittest.cc
@@ -26,10 +26,98 @@ class AstValueTest : public TestWithIsolateAndZone {
kNoSourcePosition);
}
+ const AstRawString* GetOneByteString(const char* str) {
+ return ast_value_factory_.GetOneByteString(str);
+ }
+
+ DirectHandle<String> CreateTwoByteString(const char* str) {
+ int length = static_cast<int>(strlen(str));
+ DirectHandle<SeqTwoByteString> result =
+ i_isolate()->factory()->NewRawTwoByteString(length).ToHandleChecked();
+ DisallowGarbageCollection no_gc;
+ CopyChars(result->GetChars(no_gc), str, length);
+ return result;
+ }
+
+ DirectHandle<String> CreateTwoByteStringWithNonOneByte() {
+ DirectHandle<SeqTwoByteString> result =
+ i_isolate()->factory()->NewRawTwoByteString(1).ToHandleChecked();
+ DisallowGarbageCollection no_gc;
+ result->GetChars(no_gc)[0] = 0x1234;
+ return result;
+ }
+
AstValueFactory ast_value_factory_;
AstNodeFactory ast_node_factory_;
};
+TEST_F(AstValueTest, AstRawStringAsArrayIndex) {
+ auto test_as_array_index = [&](const char* str, bool expected_success,
+ uint32_t expected_index) {
+ const AstRawString* one_byte = GetOneByteString(str);
+ EXPECT_TRUE(one_byte->is_one_byte());
+ uint32_t index = 0;
+ EXPECT_EQ(one_byte->AsArrayIndex(&index), expected_success);
+ if (expected_success) {
+ EXPECT_EQ(index, expected_index);
+ }
+ };
+
+ // Cached array index (length <= Name::kMaxCachedArrayIndexLength).
+ test_as_array_index("0", true, 0);
+ test_as_array_index("1", true, 1);
+ test_as_array_index("1234567", true, 1234567);
+
+ // Uncached array index (length > 7 and <= Name::kMaxArrayIndexSize).
+ test_as_array_index("12345678", true, 12345678);
+ test_as_array_index("1000000000", true, 1000000000);
+
+ // Max valid array index (4294967294).
+ test_as_array_index("4294967294", true, 4294967294u);
+
+ // Overflow (length 10, > 4294967294).
+ test_as_array_index("4294967295", false, 0);
+ test_as_array_index("5000000000", false, 0);
+
+ // Overflow (length > 10, > Name::kMaxArrayIndexSize).
+ test_as_array_index("10000000000", false, 0);
+
+ // Non-index strings.
+ test_as_array_index("01", false, 0);
+ test_as_array_index("foo", false, 0);
+}
+
+TEST_F(AstValueTest, GetStringNormalizesOneByteContent) {
+ DirectHandle<String> two_byte_str = CreateTwoByteString("1000000000");
+ EXPECT_TRUE(two_byte_str->IsTwoByteRepresentation());
+ const AstRawString* raw = ast_value_factory_.GetString(
+ *two_byte_str, SharedStringAccessGuardIfNeeded::NotNeeded());
+ EXPECT_TRUE(raw->is_one_byte());
+ uint32_t index = 0;
+ EXPECT_TRUE(raw->AsArrayIndex(&index));
+ EXPECT_EQ(index, 1000000000u);
+
+ // Also check that internalizing a two-byte integer-index string (unhashed or
+ // pre-hashed) canonicalizes it to one-byte in the StringTable.
+ DirectHandle<String> internalized_unhashed =
+ i_isolate()->factory()->InternalizeString(two_byte_str);
+ EXPECT_TRUE(internalized_unhashed->IsOneByteRepresentation());
+
+ DirectHandle<String> prehashed_two_byte_str =
+ CreateTwoByteString("1000000001");
+ prehashed_two_byte_str->EnsureRawHash();
+ DirectHandle<String> internalized_prehashed =
+ i_isolate()->factory()->InternalizeString(prehashed_two_byte_str);
+ EXPECT_TRUE(internalized_prehashed->IsOneByteRepresentation());
+
+ DirectHandle<String> non_one_byte_str = CreateTwoByteStringWithNonOneByte();
+ EXPECT_TRUE(non_one_byte_str->IsTwoByteRepresentation());
+ const AstRawString* raw_non_one_byte = ast_value_factory_.GetString(
+ *non_one_byte_str, SharedStringAccessGuardIfNeeded::NotNeeded());
+ EXPECT_FALSE(raw_non_one_byte->is_one_byte());
+ EXPECT_FALSE(raw_non_one_byte->AsArrayIndex(&index));
+}
+
TEST_F(AstValueTest, BigIntToBooleanIsTrue) {
EXPECT_FALSE(NewBigInt("0")->ToBooleanIsTrue());
EXPECT_FALSE(NewBigInt("0b0")->ToBooleanIsTrue());
diff --git a/deps/v8/test/unittests/parser/decls-unittest.cc b/deps/v8/test/unittests/parser/decls-unittest.cc
index bd696aa790c..6efc4b79782 100644
--- a/deps/v8/test/unittests/parser/decls-unittest.cc
+++ b/deps/v8/test/unittests/parser/decls-unittest.cc
@@ -109,7 +109,7 @@ class DeclarationContext {
int set_count_;
int query_count_;
- static DeclarationContext* GetInstance(Local<Value> data);
+ static DeclarationContext* GetInstance(Local<Data> data);
};
DeclarationContext::DeclarationContext()
@@ -184,7 +184,7 @@ void DeclarationContext::Check(const char* source, int get, int set, int query,
v8::Intercepted DeclarationContext::HandleGet(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
- DeclarationContext* context = GetInstance(info.Data());
+ DeclarationContext* context = GetInstance(info.DataV2());
context->get_count_++;
auto result = context->Get(key);
if (!result.IsEmpty()) {
@@ -197,7 +197,7 @@ v8::Intercepted DeclarationContext::HandleGet(
v8::Intercepted DeclarationContext::HandleSet(
Local<Name> key, Local<Value> value,
const v8::PropertyCallbackInfo<Boolean>& info) {
- DeclarationContext* context = GetInstance(info.Data());
+ DeclarationContext* context = GetInstance(info.DataV2());
context->set_count_++;
Maybe<bool> maybe_result = context->Set(key, value);
bool result;
@@ -212,7 +212,7 @@ v8::Intercepted DeclarationContext::HandleSet(
v8::Intercepted DeclarationContext::HandleQuery(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
- DeclarationContext* context = GetInstance(info.Data());
+ DeclarationContext* context = GetInstance(info.DataV2());
context->query_count_++;
auto result = context->Query(key);
if (!result.IsEmpty()) {
@@ -222,7 +222,7 @@ v8::Intercepted DeclarationContext::HandleQuery(
return v8::Intercepted::kNo;
}
-DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) {
+DeclarationContext* DeclarationContext::GetInstance(Local<Data> data) {
void* value = Local<External>::Cast(data)->Value(kDeclarationContextTag);
return static_cast<DeclarationContext*>(value);
}
diff --git a/deps/v8/test/unittests/profiler/heap-snapshot-scopes-unittest.cc b/deps/v8/test/unittests/profiler/heap-snapshot-scopes-unittest.cc
new file mode 100644
index 00000000000..7aef01eeed4
--- /dev/null
+++ b/deps/v8/test/unittests/profiler/heap-snapshot-scopes-unittest.cc
@@ -0,0 +1,1233 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <ostream>
+
+#include "absl/container/flat_hash_map.h"
+#include "include/v8-script.h"
+#include "src/objects/js-objects-inl.h"
+#include "src/objects/objects-inl.h"
+#include "src/objects/scope-info.h"
+#include "src/profiler/heap-profiler.h"
+#include "src/profiler/heap-snapshot-generator.h"
+#include "test/unittests/profiler/heap-snapshot-utils.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8::internal {
+
+namespace {
+
+struct SnapshotScopeId {
+ int script_node_index = -1;
+ int scope_id = -1;
+
+ bool operator==(const SnapshotScopeId& other) const = default;
+ bool operator<(const SnapshotScopeId& other) const {
+ if (script_node_index != other.script_node_index) {
+ return script_node_index < other.script_node_index;
+ }
+ return scope_id < other.scope_id;
+ }
+
+ template <typename H>
+ friend H AbslHashValue(H h, const SnapshotScopeId& s) {
+ return H::combine(std::move(h), s.script_node_index, s.scope_id);
+ }
+};
+
+struct VariableDefinition {
+ std::string name;
+ int slot_index = -1;
+ SnapshotScopeId declaring_scope;
+ std::vector<SnapshotScopeId> uses;
+};
+
+struct SnapshotSourceScopeData {
+ const HeapEntry* script_entry = nullptr;
+ int script_node_index = -1;
+ int scope_id = -1;
+ int depth = 0;
+ SnapshotScopeId id;
+ const SnapshotSourceScopeData* parent = nullptr;
+ std::vector<const SnapshotSourceScopeData*> children;
+ std::vector<std::pair<int, int>> uses; // (declaring_scope_id, slot_index)
+ std::vector<VariableDefinition> variables;
+
+ SnapshotSourceScopeData() = default;
+ SnapshotSourceScopeData(const SnapshotSourceScopeData&) = delete;
+ SnapshotSourceScopeData& operator=(const SnapshotSourceScopeData&) = delete;
+ SnapshotSourceScopeData(SnapshotSourceScopeData&&) = default;
+ SnapshotSourceScopeData& operator=(SnapshotSourceScopeData&&) = default;
+
+ const VariableDefinition* FindVariable(const std::string& name) const {
+ for (const auto& var : variables) {
+ if (var.name == name) return &var;
+ }
+ return nullptr;
+ }
+};
+
+void AssertUses(
+ const VariableDefinition* var,
+ std::initializer_list<const SnapshotSourceScopeData*> expected_scopes) {
+ ASSERT_NE(nullptr, var);
+ std::vector<SnapshotScopeId> expected_ids;
+ expected_ids.reserve(std::size(expected_scopes));
+ for (const auto* scope : expected_scopes) {
+ ASSERT_NE(nullptr, scope);
+ expected_ids.push_back(scope->id);
+ }
+ std::vector<SnapshotScopeId> actual_ids = var->uses;
+ std::sort(expected_ids.begin(), expected_ids.end());
+ std::sort(actual_ids.begin(), actual_ids.end());
+ EXPECT_EQ(actual_ids, expected_ids);
+}
+
+void LinkScopesAndVariables(std::vector<SnapshotSourceScopeData>& scopes) {
+ absl::flat_hash_map<SnapshotScopeId, SnapshotSourceScopeData*> scope_lookup;
+ for (auto& scope : scopes) {
+ scope_lookup[scope.id] = &scope;
+ }
+
+ std::vector<SnapshotSourceScopeData*> ancestor_stack;
+ for (auto& scope : scopes) {
+ while (ancestor_stack.size() > static_cast<size_t>(scope.depth)) {
+ ancestor_stack.pop_back();
+ }
+ if (!ancestor_stack.empty() &&
+ ancestor_stack.back()->script_node_index != scope.script_node_index) {
+ ancestor_stack.clear();
+ }
+ if (!ancestor_stack.empty()) {
+ scope.parent = ancestor_stack.back();
+ ancestor_stack.back()->children.push_back(&scope);
+ }
+ ancestor_stack.push_back(&scope);
+
+ for (const auto& use : scope.uses) {
+ SnapshotScopeId decl_id{scope.script_node_index, use.first};
+ int slot_idx = use.second;
+ auto it = scope_lookup.find(decl_id);
+ if (it != scope_lookup.end() && slot_idx >= 0 &&
+ static_cast<size_t>(slot_idx) < it->second->variables.size()) {
+ it->second->variables[slot_idx].uses.push_back(scope.id);
+ }
+ }
+ }
+}
+
+std::vector<SnapshotSourceScopeData> ExtractSourceScopes(
+ const HeapSnapshot* snapshot) {
+ std::vector<SnapshotSourceScopeData> result;
+ const auto& scopes = snapshot->source_scopes();
+ const auto& context_vars = snapshot->source_scope_context_vars();
+ const auto& uses = snapshot->source_scope_uses();
+
+ result.reserve(scopes.size());
+ size_t cv_offset = 0;
+ size_t uses_offset = 0;
+ for (const auto& scope : scopes) {
+ SnapshotSourceScopeData data;
+ data.script_entry = scope.script_entry;
+ data.script_node_index =
+ scope.script_entry != nullptr ? scope.script_entry->index() : -1;
+ data.scope_id = scope.scope_id;
+ data.depth = scope.depth;
+ data.id = SnapshotScopeId{data.script_node_index, data.scope_id};
+
+ data.variables.reserve(scope.scope_context_vars_count);
+ for (uint32_t c = 0; c < scope.scope_context_vars_count; ++c) {
+ data.variables.push_back(VariableDefinition{
+ context_vars[cv_offset + c], static_cast<int>(c), data.id, {}});
+ }
+ cv_offset += scope.scope_context_vars_count;
+
+ for (uint32_t u = 0; u < scope.scope_uses_count; ++u) {
+ const auto& use = uses[uses_offset + u];
+ data.uses.push_back({use.declaring_scope_id, use.slot_index});
+ }
+ uses_offset += scope.scope_uses_count;
+
+ result.push_back(std::move(data));
+ }
+ LinkScopesAndVariables(result);
+ return result;
+}
+
+// Test fixture for the scope information recorded in heap snapshots. It takes
+// a heap snapshot, extracts its scope tree and provides helpers to look up and
+// validate the scopes of a given closure.
+class HeapSnapshotScopesTest : public TestWithContext {
+ public:
+ void TakeHeapSnapshot() {
+ HeapProfiler* heap_profiler = i_isolate()->heap()->heap_profiler();
+ v8::HeapProfiler::HeapSnapshotOptions options;
+ snapshot_ = heap_profiler->TakeSnapshot(options);
+ scopes_ = ExtractSourceScopes(snapshot_);
+ }
+
+ template <typename T = JSFunction>
+ DirectHandle<T> RunJSForObject(const char* source) {
+ v8::Local<v8::Value> val = RunJS(source);
+ return Cast<T>(Utils::OpenHandle(*val));
+ }
+
+ DirectHandle<JSFunction> RunJSForClosure(const char* source) {
+ return RunJSForObject<JSFunction>(source);
+ }
+
+ static v8::MaybeLocal<v8::Module> ResolveModuleCallback(
+ v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
+ v8::Local<v8::FixedArray> import_attributes,
+ v8::Local<v8::Module> referrer) {
+ return v8::MaybeLocal<v8::Module>();
+ }
+
+ v8::Local<v8::Module> RunModule(const char* source) {
+ v8::Local<v8::String> source_string =
+ v8::String::NewFromUtf8(isolate(), source).ToLocalChecked();
+ v8::ScriptOrigin origin(
+ v8::String::NewFromUtf8(isolate(), "module.js").ToLocalChecked(), 0, 0,
+ false, -1, v8::Local<v8::Value>(), false, false, true);
+ v8::ScriptCompiler::Source script_source(source_string, origin);
+ v8::Local<v8::Module> module =
+ v8::ScriptCompiler::CompileModule(isolate(), &script_source)
+ .ToLocalChecked();
+ CHECK(
+ module->InstantiateModule(context(), ResolveModuleCallback).FromJust());
+ v8::MaybeLocal<v8::Promise> promise = module->Evaluate(context());
+ CHECK(!promise.IsEmpty());
+ CHECK_EQ(promise.ToLocalChecked()->State(), v8::Promise::kFulfilled);
+ return module;
+ }
+
+ template <typename T = JSFunction>
+ DirectHandle<T> GetModuleExport(v8::Local<v8::Module> module,
+ const char* export_name) {
+ v8::Local<v8::Object> ns = module->GetModuleNamespace().As<v8::Object>();
+ v8::Local<v8::Value> export_val =
+ ns->Get(
+ context(),
+ v8::String::NewFromUtf8(isolate(), export_name).ToLocalChecked())
+ .ToLocalChecked();
+ return Cast<T>(Utils::OpenHandle(*export_val));
+ }
+
+ DirectHandle<JSFunction> RunModuleForClosure(const char* source,
+ const char* export_name) {
+ v8::Local<v8::Module> module = RunModule(source);
+ return GetModuleExport<JSFunction>(module, export_name);
+ }
+
+ SnapshotScopeId GetScopeId(DirectHandle<JSFunction> function) {
+ return GetScopeId(*function);
+ }
+
+ SnapshotScopeId GetScopeId(Tagged<JSFunction> function) {
+ const HeapEntry* entry = GetEntryFor(i_isolate(), snapshot_, function);
+ CHECK_NOT_NULL(entry);
+ return GetScopeId(entry);
+ }
+
+ const SnapshotSourceScopeData* GetScopeForClosure(
+ DirectHandle<JSFunction> function) {
+ return GetScopeForClosure(*function);
+ }
+
+ const SnapshotSourceScopeData* GetScopeForClosure(
+ Tagged<JSFunction> function) {
+ CHECK_NOT_NULL(snapshot_);
+ SnapshotScopeId scope_id = GetScopeId(function);
+ const SnapshotSourceScopeData* scope = FindScopeById(scope_id);
+ CHECK_NOT_NULL(scope);
+ return scope;
+ }
+
+ const SnapshotSourceScopeData* FindScopeWithContextVarInScript(
+ const SnapshotSourceScopeData* scope_in_script,
+ const std::string& var_name) const {
+ CHECK_NOT_NULL(scope_in_script);
+ const HeapEntry* script_entry = scope_in_script->script_entry;
+ CHECK_NOT_NULL(script_entry);
+ for (const auto& scope : scopes_) {
+ if (scope.script_entry == script_entry &&
+ scope.FindVariable(var_name) != nullptr) {
+ return &scope;
+ }
+ }
+ return nullptr;
+ }
+
+ void CheckContextSlots(DirectHandle<JSFunction> function) {
+ CheckContextSlots(*function);
+ }
+
+ void CheckContextSlots(Tagged<JSFunction> function) {
+ CHECK_NOT_NULL(snapshot_);
+ const SnapshotSourceScopeData* func_scope = GetScopeForClosure(function);
+ ASSERT_NE(nullptr, func_scope);
+ const SnapshotSourceScopeData* curr_scope = func_scope->parent;
+
+ DisallowGarbageCollection no_gc;
+ for (Tagged<Context> ctx = function->context();
+ !ctx.is_null() && !IsNativeContext(ctx); ctx = ctx->previous()) {
+ Tagged<ScopeInfo> scope_info = ctx->scope_info();
+ int ctx_scope_id = scope_info->UniqueIdInScript();
+
+ while (curr_scope != nullptr && curr_scope->scope_id != ctx_scope_id) {
+ EXPECT_TRUE(curr_scope->variables.empty());
+ curr_scope = curr_scope->parent;
+ }
+ ASSERT_NE(nullptr, curr_scope);
+ EXPECT_EQ(curr_scope->scope_id, ctx_scope_id);
+
+ if (curr_scope->variables.empty()) {
+ // Context variable emission was disabled for this scope (e.g., class
+ // scope or a scope containing/enclosing direct eval).
+ } else {
+ int local_count = scope_info->ContextLocalCount();
+ EXPECT_EQ(curr_scope->variables.size(),
+ static_cast<size_t>(local_count));
+
+ // Check that the variables from the source scopes match exactly the
+ // order of context fields in the corresponding ScopeInfo.
+ for (int i = 0; i < local_count; ++i) {
+ const VariableDefinition& var_def = curr_scope->variables[i];
+ EXPECT_EQ(var_def.slot_index, i);
+ EXPECT_EQ(var_def.name,
+ scope_info->ContextInlinedLocalName(i)->ToCString().get());
+
+ int slot_index = scope_info->ContextHeaderLength() + i;
+ EXPECT_LT(slot_index, ctx->length());
+ }
+ }
+
+ const HeapEntry* ctx_entry = GetEntryFor(i_isolate(), snapshot_, ctx);
+ ASSERT_NE(nullptr, ctx_entry);
+ std::vector<const HeapGraphEdge*> context_var_edges;
+ for (int i = 0; i < ctx_entry->children_count(); ++i) {
+ const HeapGraphEdge* edge = ctx_entry->child(i);
+ if (edge->type() == HeapGraphEdge::kContextVariable) {
+ context_var_edges.push_back(edge);
+ }
+ }
+ if (!curr_scope->variables.empty()) {
+ ASSERT_EQ(curr_scope->variables.size(), context_var_edges.size());
+ for (size_t i = 0; i < context_var_edges.size(); ++i) {
+ EXPECT_EQ(curr_scope->variables[i].name,
+ context_var_edges[i]->name());
+ }
+ }
+ if (!IsNativeContext(ctx->previous())) {
+ const HeapGraphEdge* prev_edge = GetNamedEdge(*ctx_entry, "previous");
+ ASSERT_NE(nullptr, prev_edge);
+ const HeapEntry* prev_entry =
+ GetEntryFor(i_isolate(), snapshot_, ctx->previous());
+ EXPECT_EQ(prev_entry, prev_edge->to());
+ }
+
+ curr_scope = curr_scope->parent;
+ }
+
+ while (curr_scope != nullptr) {
+ EXPECT_TRUE(curr_scope->variables.empty());
+ curr_scope = curr_scope->parent;
+ }
+ }
+
+ HeapSnapshot* snapshot() const { return snapshot_; }
+ const std::vector<SnapshotSourceScopeData>& scopes() const { return scopes_; }
+ std::vector<SnapshotSourceScopeData>& scopes() { return scopes_; }
+
+ private:
+ const SnapshotSourceScopeData* FindScopeById(SnapshotScopeId id) const {
+ for (const auto& scope : scopes_) {
+ if (scope.id == id) return &scope;
+ }
+ return nullptr;
+ }
+
+ SnapshotScopeId GetScopeId(const HeapEntry* function_entry) {
+ const HeapGraphEdge* shared_edge = GetNamedEdge(*function_entry, "shared");
+ const HeapEntry* shared_entry =
+ shared_edge != nullptr ? shared_edge->to() : function_entry;
+
+ const HeapGraphEdge* script_edge = GetNamedEdge(*shared_entry, "script");
+ CHECK_NOT_NULL(script_edge);
+ const HeapEntry* script_entry = script_edge->to();
+
+ std::optional<int> scope_id = GetIntEdge(shared_entry, "scope_id");
+ CHECK(scope_id.has_value());
+ return SnapshotScopeId{script_entry->index(), *scope_id};
+ }
+
+ HeapSnapshot* snapshot_ = nullptr;
+ std::vector<SnapshotSourceScopeData> scopes_;
+};
+
+} // namespace
+
+TEST_F(HeapSnapshotScopesTest, Basic) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer(a) {\n"
+ " let b = 1;\n"
+ " b = 2;\n"
+ " {\n"
+ " let blockScoped = 3;\n"
+ " b = blockScoped;\n"
+ " }\n"
+ " function inner(c) {\n"
+ " let d = 2;\n"
+ " return a + b + c + d;\n"
+ " }\n"
+ " return inner;\n"
+ "}\n"
+ "outer(10);\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner->script_entry);
+
+ const SnapshotSourceScopeData* outer = inner->parent;
+ ASSERT_NE(nullptr, outer);
+ ASSERT_EQ(2u, outer->children.size());
+ EXPECT_EQ(inner, outer->children[0]);
+ const SnapshotSourceScopeData* block_scope = outer->children[1];
+
+ const VariableDefinition* var_a = outer->FindVariable("a");
+ const VariableDefinition* var_b = outer->FindVariable("b");
+ AssertUses(var_a, {inner});
+ // Currently all uses of a context variable are added. Even if its within the
+ // defining function.
+ AssertUses(var_b, {outer, block_scope, inner});
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ClosesOverVariable) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " let captured = 1;\n"
+ " let blockCaptured = 2;\n"
+ " let stackOnly = 3;\n"
+ " return function inner() {\n"
+ " {\n"
+ " let blockScoped = 4;\n"
+ " blockCaptured += blockScoped;\n"
+ " }\n"
+ " return captured;\n"
+ " };\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+
+ ASSERT_EQ(1u, inner_scope->children.size());
+ const SnapshotSourceScopeData* block_scope = inner_scope->children[0];
+
+ const SnapshotSourceScopeData* outer = inner_scope->parent;
+ ASSERT_NE(nullptr, outer);
+ const VariableDefinition* captured = outer->FindVariable("captured");
+ EXPECT_EQ(0, captured->slot_index);
+ AssertUses(captured, {inner_scope});
+
+ const VariableDefinition* block_captured =
+ outer->FindVariable("blockCaptured");
+ EXPECT_EQ(1, block_captured->slot_index);
+ AssertUses(block_captured, {block_scope});
+
+ EXPECT_EQ(nullptr, outer->FindVariable("stackOnly"));
+ EXPECT_EQ(nullptr, block_scope->FindVariable("blockScoped"));
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, UsesInDifferentClosures) {
+ DirectHandle<JSArray> funcs = RunJSForObject<JSArray>(
+ "function outer() {\n"
+ " let captured = 1;\n"
+ " function first() {\n"
+ " return captured + captured;\n"
+ " }\n"
+ " const second = () => captured;\n"
+ " return [first, second];\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ DirectHandle<JSFunction> first_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 0).ToHandleChecked());
+ DirectHandle<JSFunction> second_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 1).ToHandleChecked());
+
+ const SnapshotSourceScopeData* first = GetScopeForClosure(*first_fn);
+ const SnapshotSourceScopeData* second = GetScopeForClosure(*second_fn);
+
+ EXPECT_EQ(first->parent, second->parent);
+ const SnapshotSourceScopeData* outer = first->parent;
+ ASSERT_NE(nullptr, outer);
+
+ const VariableDefinition* captured = outer->FindVariable("captured");
+ AssertUses(captured, {first, first, second});
+ CheckContextSlots(first_fn);
+ CheckContextSlots(second_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, FreeVariables) {
+ DirectHandle<JSFunction> arrow = RunJSForClosure(
+ "function outer() {\n"
+ " return () => missing + missing;\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* arrow_scope = GetScopeForClosure(*arrow);
+ EXPECT_TRUE(arrow_scope->variables.empty());
+ EXPECT_TRUE(arrow_scope->uses.empty());
+
+ // Free variable `missing` should not be allocated as a context variable in
+ // outer or the arrow function.
+ EXPECT_EQ(nullptr, FindScopeWithContextVarInScript(arrow_scope, "missing"));
+ CheckContextSlots(arrow);
+}
+
+TEST_F(HeapSnapshotScopesTest, GlobalVariables) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "let scriptLet = 1;\n"
+ "const scriptConst = 2;\n"
+ "var scriptVar = 3;\n"
+ "function inner() {\n"
+ " return scriptLet + scriptConst + scriptVar;\n"
+ "}\n"
+ "inner;\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner = GetScopeForClosure(*inner_fn);
+
+ // Script scope contains lexical variables (let and const) in context vars.
+ const SnapshotSourceScopeData* script_scope = inner->parent;
+ ASSERT_NE(nullptr, script_scope);
+ EXPECT_EQ(0, script_scope->depth);
+ EXPECT_EQ(nullptr, script_scope->parent);
+ EXPECT_NE(nullptr, script_scope->FindVariable("scriptConst"));
+ // Global var is on the global object, not in script context.
+ EXPECT_EQ(nullptr, script_scope->FindVariable("scriptVar"));
+
+ const VariableDefinition* let_var = script_scope->FindVariable("scriptLet");
+ const VariableDefinition* const_var =
+ script_scope->FindVariable("scriptConst");
+ AssertUses(let_var, {inner});
+ AssertUses(const_var, {inner});
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, FunctionVarCaptured) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " var varCaptured = 1;\n"
+ " let letCaptured = 2;\n"
+ " const constCaptured = 3;\n"
+ " var varUnused = 4;\n"
+ " return function inner() {\n"
+ " return varCaptured + letCaptured + constCaptured;\n"
+ " };\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner = GetScopeForClosure(*inner_fn);
+
+ const SnapshotSourceScopeData* outer = inner->parent;
+ ASSERT_NE(nullptr, outer);
+ const VariableDefinition* var = outer->FindVariable("varCaptured");
+ const VariableDefinition* let_var = outer->FindVariable("letCaptured");
+ const VariableDefinition* const_var = outer->FindVariable("constCaptured");
+ EXPECT_EQ(nullptr, outer->FindVariable("varUnused"));
+
+ AssertUses(var, {inner});
+ AssertUses(let_var, {inner});
+ AssertUses(const_var, {inner});
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ForOfBodyScope) {
+ DirectHandle<JSArray> closures = RunJSForObject<JSArray>(
+ "function makeClosures() {\n"
+ " const closures = [];\n"
+ " for (const item of [1, 2]) {\n"
+ " const captured = {item};\n"
+ " const unused = 42;\n"
+ " closures.push(function blockInner() {\n"
+ " return captured;\n"
+ " });\n"
+ " }\n"
+ " return closures;\n"
+ "}\n"
+ "makeClosures();\n");
+
+ TakeHeapSnapshot();
+ DirectHandle<JSFunction> block_inner_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), closures, 0).ToHandleChecked());
+ const SnapshotSourceScopeData* block_inner =
+ GetScopeForClosure(*block_inner_fn);
+
+ const SnapshotSourceScopeData* body_scope = block_inner->parent;
+ ASSERT_NE(nullptr, body_scope);
+ const VariableDefinition* captured = body_scope->FindVariable("captured");
+ AssertUses(captured, {block_inner});
+ EXPECT_EQ(nullptr, body_scope->FindVariable("unused"));
+
+ // `item` is only used locally to initialize `captured` and is not closed
+ // over, so it should not be context-allocated.
+ const SnapshotSourceScopeData* loop_scope = body_scope->parent;
+ ASSERT_NE(nullptr, loop_scope);
+ EXPECT_EQ(nullptr, loop_scope->FindVariable("item"));
+ EXPECT_EQ(nullptr, FindScopeWithContextVarInScript(body_scope, "item"));
+ CheckContextSlots(block_inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ForOfIterationVariable) {
+ DirectHandle<JSArray> closures = RunJSForObject<JSArray>(
+ "function makeClosures(values) {\n"
+ " const closures = [];\n"
+ " for (const item of values) {\n"
+ " closures.push(() => item);\n"
+ " }\n"
+ " return closures;\n"
+ "}\n"
+ "makeClosures([1, 2]);\n");
+
+ TakeHeapSnapshot();
+ DirectHandle<JSFunction> arrow_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), closures, 0).ToHandleChecked());
+ const SnapshotSourceScopeData* arrow = GetScopeForClosure(*arrow_fn);
+
+ const SnapshotSourceScopeData* loop_scope = arrow->parent;
+ ASSERT_NE(nullptr, loop_scope);
+ const VariableDefinition* item_var = loop_scope->FindVariable("item");
+ AssertUses(item_var, {arrow});
+ CheckContextSlots(arrow_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ClassicForLoop) {
+ DirectHandle<JSArray> callbacks = RunJSForObject<JSArray>(
+ "function makeCallbacks() {\n"
+ " const callbacks = [];\n"
+ " for (let index = 0; index < 2; ++index) {\n"
+ " callbacks.push(() => index);\n"
+ " }\n"
+ " return callbacks;\n"
+ "}\n"
+ "makeCallbacks();\n");
+
+ TakeHeapSnapshot();
+ DirectHandle<JSFunction> arrow_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), callbacks, 0).ToHandleChecked());
+ const SnapshotSourceScopeData* arrow = GetScopeForClosure(*arrow_fn);
+
+ const SnapshotSourceScopeData* loop_body_scope = arrow->parent;
+ ASSERT_NE(nullptr, loop_body_scope);
+ const VariableDefinition* index_var = loop_body_scope->FindVariable("index");
+
+ // The iteration scope itself uses index (in condition/update), and the
+ // inner arrow closure also uses index.
+ AssertUses(index_var, {loop_body_scope, loop_body_scope, arrow});
+ CheckContextSlots(arrow_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, Catch) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function makeHandler() {\n"
+ " try {\n"
+ " throw new Error('boom');\n"
+ " } catch (error) {\n"
+ " const detail = error.message;\n"
+ " const unused = 42;\n"
+ " return function inner() {\n"
+ " return [error, detail];\n"
+ " };\n"
+ " }\n"
+ "}\n"
+ "makeHandler();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner = GetScopeForClosure(*inner_fn);
+
+ const SnapshotSourceScopeData* catch_block = inner->parent;
+ ASSERT_NE(nullptr, catch_block);
+
+ const SnapshotSourceScopeData* catch_scope = catch_block->parent;
+ ASSERT_NE(nullptr, catch_scope);
+
+ EXPECT_EQ(nullptr, catch_block->FindVariable("unused"));
+
+ const VariableDefinition* error_var = catch_scope->FindVariable("error");
+ const VariableDefinition* detail_var = catch_block->FindVariable("detail");
+
+ AssertUses(error_var, {catch_block, inner});
+ AssertUses(detail_var, {inner});
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, NestedFunctions) {
+ DirectHandle<JSFunction> nested_inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " let outerCaptured = 1;\n"
+ " return function inner() {\n"
+ " let innerCaptured = 2;\n"
+ " return function nested_inner() {\n"
+ " return outerCaptured + innerCaptured;\n"
+ " };\n"
+ " };\n"
+ "}\n"
+ "outer()();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* nested_inner =
+ GetScopeForClosure(*nested_inner_fn);
+
+ const SnapshotSourceScopeData* inner = nested_inner->parent;
+ ASSERT_NE(nullptr, inner);
+ const SnapshotSourceScopeData* outer = inner->parent;
+ ASSERT_NE(nullptr, outer);
+
+ const VariableDefinition* outer_captured =
+ outer->FindVariable("outerCaptured");
+ const VariableDefinition* inner_captured =
+ inner->FindVariable("innerCaptured");
+
+ // inner does not use outerCaptured directly; nested_inner uses both.
+ AssertUses(outer_captured, {nested_inner});
+ AssertUses(inner_captured, {nested_inner});
+ CheckContextSlots(nested_inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, BlockAndShadowingNoContextUses) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " let value = 1;\n"
+ " { value++; }\n"
+ " return function inner(value) {\n"
+ " return value;\n"
+ " };\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* inner = GetScopeForClosure(*inner_fn);
+
+ // Neither outer's value nor inner's value should be context-allocated.
+ EXPECT_EQ(nullptr, FindScopeWithContextVarInScript(inner, "value"));
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ShadowingCaptured) {
+ DirectHandle<JSFunction> arrow_fn = RunJSForClosure(
+ "function outer() {\n"
+ " let value = 1;\n"
+ " function inner(value) {\n"
+ " return () => value;\n"
+ " }\n"
+ " return inner(2);\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* arrow = GetScopeForClosure(*arrow_fn);
+
+ const SnapshotSourceScopeData* inner = arrow->parent;
+ ASSERT_NE(nullptr, inner);
+ const SnapshotSourceScopeData* outer = inner->parent;
+ ASSERT_NE(nullptr, outer);
+ EXPECT_EQ(nullptr, outer->FindVariable("value"));
+
+ const VariableDefinition* value_var = inner->FindVariable("value");
+ ASSERT_NE(nullptr, value_var);
+ EXPECT_EQ(inner, arrow->parent);
+ AssertUses(value_var, {arrow});
+ CheckContextSlots(arrow_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ClassMethods) {
+ RunJS(
+ "function outer() {\n"
+ " let instanceCaptured = 1;\n"
+ " let staticCaptured = 2;\n"
+ " let unused = 3;\n"
+ " class Target {\n"
+ " instanceMethod() {\n"
+ " return instanceCaptured;\n"
+ " }\n"
+ " static staticMethod() {\n"
+ " return staticCaptured;\n"
+ " }\n"
+ " }\n"
+ " return Target;\n"
+ "}\n"
+ "var Target = outer();\n");
+
+ DirectHandle<JSFunction> instance_method_fn =
+ RunJSForClosure("new Target().instanceMethod");
+ DirectHandle<JSFunction> static_method_fn =
+ RunJSForClosure("Target.staticMethod");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* instance_method =
+ GetScopeForClosure(*instance_method_fn);
+ const SnapshotSourceScopeData* static_method =
+ GetScopeForClosure(*static_method_fn);
+ EXPECT_NE(instance_method, static_method);
+ EXPECT_EQ(instance_method->parent, static_method->parent);
+
+ const SnapshotSourceScopeData* class_scope = instance_method->parent;
+ ASSERT_NE(nullptr, class_scope);
+ const SnapshotSourceScopeData* outer = class_scope->parent;
+ ASSERT_NE(nullptr, outer);
+
+ const VariableDefinition* instance_captured =
+ outer->FindVariable("instanceCaptured");
+ const VariableDefinition* static_captured =
+ outer->FindVariable("staticCaptured");
+ EXPECT_EQ(nullptr, outer->FindVariable("unused"));
+
+ AssertUses(instance_captured, {instance_method});
+ AssertUses(static_captured, {static_method});
+ CheckContextSlots(instance_method_fn);
+ CheckContextSlots(static_method_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, ClassFieldInitializer) {
+ DirectHandle<JSFunction> arrow = RunJSForClosure(
+ "class Target {\n"
+ " instanceField = (() => {\n"
+ " let captured = 1;\n"
+ " let unused = 2;\n"
+ " return () => captured;\n"
+ " })();\n"
+ "}\n"
+ "new Target().instanceField;\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* inner_arrow = GetScopeForClosure(*arrow);
+ const SnapshotSourceScopeData* iife = inner_arrow->parent;
+ ASSERT_NE(nullptr, iife);
+ const VariableDefinition* captured = iife->FindVariable("captured");
+ EXPECT_EQ(nullptr, iife->FindVariable("unused"));
+
+ AssertUses(captured, {inner_arrow});
+ CheckContextSlots(arrow);
+}
+
+TEST_F(HeapSnapshotScopesTest, ClassPrivateFields) {
+ RunJS(
+ "function outer() {\n"
+ " let outerCaptured = 1;\n"
+ " let outerUnused = 2;\n"
+ " class Target {\n"
+ " #x = 10;\n"
+ " #y = 20;\n"
+ " method() {\n"
+ " return this.#x + outerCaptured;\n"
+ " }\n"
+ " }\n"
+ " return Target;\n"
+ "}\n"
+ "var Target = outer();\n");
+
+ DirectHandle<JSFunction> method_fn = RunJSForClosure("new Target().method");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* method_scope = GetScopeForClosure(*method_fn);
+ ASSERT_NE(nullptr, method_scope);
+
+ const SnapshotSourceScopeData* class_scope = method_scope->parent;
+ ASSERT_NE(nullptr, class_scope);
+ const SnapshotSourceScopeData* outer_scope = class_scope->parent;
+ ASSERT_NE(nullptr, outer_scope);
+
+ const VariableDefinition* outer_captured =
+ outer_scope->FindVariable("outerCaptured");
+ ASSERT_NE(nullptr, outer_captured);
+ // Class scopes contain private fields and methods (#x, #y) for which uses
+ // across closures are currently not tracked. Therefore, context variables
+ // are omitted for class scopes to disable dead context analysis.
+ EXPECT_EQ(nullptr, class_scope->FindVariable("#x"));
+ EXPECT_EQ(nullptr, class_scope->FindVariable("#y"));
+
+ AssertUses(outer_captured, {method_scope});
+
+ CheckContextSlots(method_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, DestructuringCaptured) {
+ DirectHandle<JSFunction> arrow = RunJSForClosure(
+ "function outer() {\n"
+ " let {a, b: [c], d = 4} = {a: 1, b: [2]};\n"
+ " let unused = 5;\n"
+ " return () => a + c + d;\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+ const SnapshotSourceScopeData* arrow_scope = GetScopeForClosure(*arrow);
+
+ const SnapshotSourceScopeData* outer = arrow_scope->parent;
+ ASSERT_NE(nullptr, outer);
+
+ const VariableDefinition* a_var = outer->FindVariable("a");
+ const VariableDefinition* c_var = outer->FindVariable("c");
+ const VariableDefinition* d_var = outer->FindVariable("d");
+ EXPECT_EQ(nullptr, outer->FindVariable("unused"));
+
+ AssertUses(a_var, {arrow_scope});
+ AssertUses(c_var, {arrow_scope});
+ AssertUses(d_var, {arrow_scope});
+ CheckContextSlots(arrow);
+}
+
+TEST_F(HeapSnapshotScopesTest, ModuleScope) {
+ v8::Local<v8::Module> module = RunModule(
+ "let moduleVar = 1;\n"
+ "let unused = 2;\n"
+ "export function outer() {\n"
+ " let outerVar = 3;\n"
+ " function inner() {\n"
+ " return moduleVar + outerVar;\n"
+ " }\n"
+ " return inner;\n"
+ "}\n"
+ "export const innerFn = outer();\n");
+
+ DirectHandle<JSFunction> outer_fn =
+ GetModuleExport<JSFunction>(module, "outer");
+ DirectHandle<JSFunction> inner_fn =
+ GetModuleExport<JSFunction>(module, "innerFn");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* outer_scope = GetScopeForClosure(*outer_fn);
+ ASSERT_NE(nullptr, outer_scope);
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+
+ const SnapshotSourceScopeData* module_scope = outer_scope->parent;
+ ASSERT_NE(nullptr, module_scope);
+ EXPECT_EQ(-2, module_scope->scope_id);
+ EXPECT_EQ(0, module_scope->depth);
+ EXPECT_EQ(nullptr, module_scope->parent);
+
+ EXPECT_EQ(outer_scope, inner_scope->parent);
+
+ const VariableDefinition* module_var =
+ module_scope->FindVariable("moduleVar");
+ ASSERT_NE(nullptr, module_var);
+ EXPECT_EQ(0, module_var->slot_index);
+ AssertUses(module_var, {inner_scope});
+
+ const VariableDefinition* outer_var = outer_scope->FindVariable("outerVar");
+ ASSERT_NE(nullptr, outer_var);
+ EXPECT_EQ(0, outer_var->slot_index);
+ AssertUses(outer_var, {inner_scope});
+
+ EXPECT_EQ(nullptr, module_scope->FindVariable("unused"));
+ CheckContextSlots(outer_fn);
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, CapturedThis) {
+ DirectHandle<JSArray> funcs = RunJSForObject<JSArray>(
+ "function outer() {\n"
+ " const first = () => this;\n"
+ " const second = () => this;\n"
+ " return [first, second];\n"
+ "}\n"
+ "outer.call({a: 1});\n");
+
+ TakeHeapSnapshot();
+
+ DirectHandle<JSFunction> first_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 0).ToHandleChecked());
+ DirectHandle<JSFunction> second_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 1).ToHandleChecked());
+
+ const SnapshotSourceScopeData* first_scope = GetScopeForClosure(*first_fn);
+ ASSERT_NE(nullptr, first_scope);
+ const SnapshotSourceScopeData* second_scope = GetScopeForClosure(*second_fn);
+ ASSERT_NE(nullptr, second_scope);
+
+ EXPECT_EQ(first_scope->parent, second_scope->parent);
+ const SnapshotSourceScopeData* outer_scope = first_scope->parent;
+ ASSERT_NE(nullptr, outer_scope);
+
+ const VariableDefinition* this_var = outer_scope->FindVariable("this");
+ ASSERT_NE(nullptr, this_var);
+ EXPECT_EQ(0, this_var->slot_index);
+ AssertUses(this_var, {first_scope, second_scope});
+
+ CheckContextSlots(first_fn);
+ CheckContextSlots(second_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, CapturedThisMultipleUses) {
+ DirectHandle<JSFunction> arrow_fn = RunJSForClosure(
+ "function outer() {\n"
+ " return () => [this, this];\n"
+ "}\n"
+ "outer.call({a: 1});\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* arrow_scope = GetScopeForClosure(*arrow_fn);
+ ASSERT_NE(nullptr, arrow_scope);
+
+ const SnapshotSourceScopeData* outer_scope = arrow_scope->parent;
+ ASSERT_NE(nullptr, outer_scope);
+
+ const VariableDefinition* this_var = outer_scope->FindVariable("this");
+ ASSERT_NE(nullptr, this_var);
+ EXPECT_EQ(0, this_var->slot_index);
+ // The arrow function is only recorded once here (not both uses).
+ AssertUses(this_var, {arrow_scope});
+
+ CheckContextSlots(arrow_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, EvalScript) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "eval(\n"
+ " 'function evalOuter() {\\n' +\n"
+ " ' let evalVar = 1;\\n' +\n"
+ " ' let unused = 2;\\n' +\n"
+ " ' return function evalInner() {\\n' +\n"
+ " ' return evalVar;\\n' +\n"
+ " ' };\\n' +\n"
+ " '}\\n' +\n"
+ " 'evalOuter();\\n');\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+
+ const SnapshotSourceScopeData* outer_scope = inner_scope->parent;
+ ASSERT_NE(nullptr, outer_scope);
+
+ const SnapshotSourceScopeData* eval_scope = outer_scope->parent;
+ ASSERT_NE(nullptr, eval_scope);
+ EXPECT_EQ(-2, eval_scope->scope_id);
+ EXPECT_EQ(0, eval_scope->depth);
+ EXPECT_EQ(nullptr, eval_scope->parent);
+
+ const VariableDefinition* eval_var = outer_scope->FindVariable("evalVar");
+ ASSERT_NE(nullptr, eval_var);
+ EXPECT_EQ(0, eval_var->slot_index);
+ AssertUses(eval_var, {inner_scope});
+ EXPECT_EQ(nullptr, outer_scope->FindVariable("unused"));
+
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, EvalScriptWithEnclosingScope) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " let outerVar = 1;\n"
+ " return eval(\n"
+ " 'let evalVar = 2;\\n' +\n"
+ " 'function inner() {\\n' +\n"
+ " ' return outerVar + evalVar;\\n' +\n"
+ " '}\\n' +\n"
+ " 'inner;\\n');\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+
+ const SnapshotSourceScopeData* eval_scope = inner_scope->parent;
+ ASSERT_NE(nullptr, eval_scope);
+ EXPECT_EQ(-2, eval_scope->scope_id);
+ EXPECT_EQ(0, eval_scope->depth);
+ EXPECT_EQ(nullptr, eval_scope->parent);
+
+ const VariableDefinition* eval_var = eval_scope->FindVariable("evalVar");
+ ASSERT_NE(nullptr, eval_var);
+ EXPECT_EQ(0, eval_var->slot_index);
+ AssertUses(eval_var, {inner_scope});
+
+ DirectHandle<JSFunction> outer_fn = RunJSForClosure("outer");
+ const SnapshotSourceScopeData* outer_scope = GetScopeForClosure(*outer_fn);
+ ASSERT_NE(nullptr, outer_scope);
+
+ // Since outer calls eval directly, variable emission is disabled for its
+ // scope to disable dead context analysis.
+ EXPECT_EQ(0u, outer_scope->variables.size());
+ EXPECT_EQ(nullptr, outer_scope->FindVariable("outerVar"));
+
+ // Since eval scripts are parsed self-contained during heap snapshot
+ // generation without deserializing the outer ScopeInfo chain, inner only
+ // resolves uses of variables declared within the eval script (evalVar).
+ // References to outerVar are unresolved / treated as dynamic globals.
+ std::vector<std::pair<int, int>> expected_uses = {
+ {eval_scope->scope_id, eval_var->slot_index},
+ };
+ EXPECT_EQ(inner_scope->uses, expected_uses);
+
+ CheckContextSlots(outer_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, StrictEvalScript) {
+ // Eval inside a strict function inherits strict mode from the caller.
+ // In strict mode eval, 'var' declarations are scoped to the eval scope
+ // itself rather than leaking out, and can be allocated to context slots.
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " return eval(\n"
+ " 'var evalVar = 1;\\n' +\n"
+ " 'function inner() {\\n' +\n"
+ " ' return evalVar;\\n' +\n"
+ " '}\\n' +\n"
+ " 'inner;\\n');\n"
+ "}\n"
+ "outer();\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+
+ const SnapshotSourceScopeData* eval_scope = inner_scope->parent;
+ ASSERT_NE(nullptr, eval_scope);
+ EXPECT_EQ(-2, eval_scope->scope_id);
+ EXPECT_EQ(0, eval_scope->depth);
+ EXPECT_EQ(nullptr, eval_scope->parent);
+
+ // In strict eval, 'var evalVar' is a local of the eval scope and allocated
+ // to a context slot since 'inner' closes over it.
+ const VariableDefinition* eval_var = eval_scope->FindVariable("evalVar");
+ ASSERT_NE(nullptr, eval_var);
+ EXPECT_EQ(0, eval_var->slot_index);
+ AssertUses(eval_var, {inner_scope});
+
+ DirectHandle<JSFunction> outer_fn = RunJSForClosure("outer");
+ CheckContextSlots(outer_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, DirectEvalDisablesVariableEmission) {
+ // Test that direct eval in an inner scope disables variable emission
+ // for both the inner scope and its enclosing outer scopes, while an
+ // unaffected sibling function still has its context variables emitted.
+ DirectHandle<JSArray> funcs = RunJSForObject<JSArray>(
+ "function enclosing() {\n"
+ " let outerVar = 1;\n"
+ " function middle() {\n"
+ " let middleVar = 2;\n"
+ " eval('middleVar');\n"
+ " }\n"
+ " function sibling() {\n"
+ " let siblingVar = 3;\n"
+ " return function innerOfSibling() {\n"
+ " return siblingVar;\n"
+ " };\n"
+ " }\n"
+ " middle();\n"
+ " const inner = sibling();\n"
+ " return [enclosing, middle, sibling, inner];\n"
+ "}\n"
+ "enclosing();\n");
+
+ TakeHeapSnapshot();
+
+ DirectHandle<JSFunction> enclosing_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 0).ToHandleChecked());
+ DirectHandle<JSFunction> middle_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 1).ToHandleChecked());
+ DirectHandle<JSFunction> sibling_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 2).ToHandleChecked());
+ DirectHandle<JSFunction> inner_fn = Cast<JSFunction>(
+ JSReceiver::GetElement(i_isolate(), funcs, 3).ToHandleChecked());
+
+ const SnapshotSourceScopeData* enclosing_scope =
+ GetScopeForClosure(*enclosing_fn);
+ ASSERT_NE(nullptr, enclosing_scope);
+
+ // Both enclosing and middle contain or have inner scope calling eval,
+ // so variable emission must be disabled for both.
+ EXPECT_EQ(0u, enclosing_scope->variables.size());
+ EXPECT_EQ(nullptr, enclosing_scope->FindVariable("outerVar"));
+
+ const SnapshotSourceScopeData* middle_scope = GetScopeForClosure(*middle_fn);
+ ASSERT_NE(nullptr, middle_scope);
+ EXPECT_EQ(enclosing_scope, middle_scope->parent);
+ EXPECT_EQ(0u, middle_scope->variables.size());
+ EXPECT_EQ(nullptr, middle_scope->FindVariable("middleVar"));
+
+ // The sibling function does not call eval and none of its inner scopes
+ // call eval, so its context variables must still be emitted.
+ const SnapshotSourceScopeData* sibling_scope =
+ GetScopeForClosure(*sibling_fn);
+ ASSERT_NE(nullptr, sibling_scope);
+ EXPECT_EQ(enclosing_scope, sibling_scope->parent);
+
+ const VariableDefinition* sibling_var =
+ sibling_scope->FindVariable("siblingVar");
+ ASSERT_NE(nullptr, sibling_var);
+ EXPECT_EQ(0, sibling_var->slot_index);
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+ EXPECT_EQ(sibling_scope, inner_scope->parent);
+ AssertUses(sibling_var, {inner_scope});
+
+ CheckContextSlots(enclosing_fn);
+ CheckContextSlots(middle_fn);
+ CheckContextSlots(sibling_fn);
+ CheckContextSlots(inner_fn);
+}
+
+TEST_F(HeapSnapshotScopesTest, WithStatement) {
+ DirectHandle<JSFunction> inner_fn = RunJSForClosure(
+ "function outer(obj) {\n"
+ " let outerCaptured = 1;\n"
+ " let outerUnused = 2;\n"
+ " with (obj) {\n"
+ " return function inner() {\n"
+ " return outerCaptured;\n"
+ " };\n"
+ " }\n"
+ "}\n"
+ "outer({a: 10});\n");
+
+ TakeHeapSnapshot();
+
+ const SnapshotSourceScopeData* inner_scope = GetScopeForClosure(*inner_fn);
+ ASSERT_NE(nullptr, inner_scope);
+
+ const SnapshotSourceScopeData* with_scope = inner_scope->parent;
+ ASSERT_NE(nullptr, with_scope);
+ EXPECT_TRUE(with_scope->variables.empty());
+
+ const SnapshotSourceScopeData* outer_scope = with_scope->parent;
+ ASSERT_NE(nullptr, outer_scope);
+
+ const VariableDefinition* outer_captured =
+ outer_scope->FindVariable("outerCaptured");
+ ASSERT_NE(nullptr, outer_captured);
+ EXPECT_EQ(0, outer_captured->slot_index);
+ EXPECT_EQ(nullptr, outer_scope->FindVariable("outerUnused"));
+
+ // The potential use of outerCaptured should be reported.
+ AssertUses(outer_captured, {inner_scope});
+
+ CheckContextSlots(inner_fn);
+}
+
+} // namespace v8::internal
diff --git a/deps/v8/test/unittests/profiler/heap-snapshot-utils.h b/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
index 94d9deee28c..7d133cd4e54 100644
--- a/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
+++ b/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
@@ -45,6 +45,12 @@ const HeapEntry* GetEntryFor(Isolate* isolate, HeapSnapshot* snapshot,
cppgc::internal::HeapObjectHeader::FromObject(object));
}
+template <typename T>
+const HeapEntry* GetEntryFor(Isolate* isolate, HeapSnapshot* snapshot,
+ DirectHandle<T> handle) {
+ return GetEntryFor(isolate, snapshot, *handle);
+}
+
} // namespace v8::internal
#endif // V8_UNITTESTS_PROFILER_HEAP_SNAPSHOT_UTILS_H_
diff --git a/deps/v8/test/unittests/regexp/regexp-unittest.cc b/deps/v8/test/unittests/regexp/regexp-unittest.cc
index f27ed6e952e..e734bac8d75 100644
--- a/deps/v8/test/unittests/regexp/regexp-unittest.cc
+++ b/deps/v8/test/unittests/regexp/regexp-unittest.cc
@@ -6,6 +6,7 @@
#include <cstdlib>
#include <memory>
#include <sstream>
+#include <vector>
#include "include/v8-context.h"
#include "include/v8-initialization.h"
@@ -35,6 +36,12 @@
#include "test/common/flag-utils.h"
#include "test/unittests/test-utils.h"
+#ifdef V8_INTL_SUPPORT
+#include "src/regexp/special-case.h"
+#include "unicode/locid.h"
+#include "unicode/unistr.h"
+#endif
+
namespace v8 {
namespace internal {
@@ -909,6 +916,95 @@ TEST_F(RegExpTest, MacroAssemblerNativeBacktrack) {
CHECK_EQ(regexp::NativeRegExpMacroAssembler::FAILURE, result);
}
+// A power-of-two mask compared against zero or against itself tests a single
+// bit of the loaded characters; arm64 folds each such check into tbz/tbnz.
+// Cover c == 0 and c == mask for both checks, with an explicit label and with
+// the implicit backtrack target, and bits above 7 through multi-character
+// loads. Every exit records itself in register 2 so the test can tell which
+// check fired.
+TEST_F(RegExpTest, MacroAssemblerNativeCheckCharacterAfterAndSingleBit) {
+ ContextInitializer initializer;
+ Factory* factory = i_isolate()->factory();
+ Zone zone(i_isolate()->allocator(), ZONE_NAME);
+
+ ArchRegExpMacroAssembler m(i_isolate(), &zone,
+ regexp::NativeRegExpMacroAssembler::LATIN1, 4);
+
+ constexpr int kMatched = 1;
+ constexpr int kLabel = 2;
+ constexpr int kBacktrack = 3;
+
+ Label on_label, on_backtrack;
+ m.PushBacktrack(&on_backtrack);
+ // All four characters as one word: bit 31 is bit 7 of the last character.
+ m.LoadCurrentCharacter(0, nullptr, true, 4);
+ m.CheckCharacterAfterAnd(0x80000000u, 0x80000000u, &on_label);
+ // Two characters as a half-word: bit 15 is bit 7 of the second character.
+ m.LoadCurrentCharacter(0, nullptr, false, 2);
+ m.CheckNotCharacterAfterAnd(0, 0x8000, nullptr);
+ // Single characters.
+ m.LoadCurrentCharacter(0, nullptr, false);
+ m.CheckNotCharacterAfterAnd(0, 0x80, nullptr);
+ m.CheckNotCharacterAfterAnd(0x01, 0x01, &on_label);
+ m.LoadCurrentCharacter(1, nullptr, false);
+ m.CheckCharacterAfterAnd(0, 0x40, nullptr);
+ m.CheckCharacterAfterAnd(0x20, 0x20, &on_label);
+ m.WriteCurrentPositionToRegister(0, 0);
+ m.WriteCurrentPositionToRegister(1, 4);
+ m.WriteCurrentPositionToRegister(2, kMatched);
+ m.Succeed();
+ m.Bind(&on_label);
+ m.WriteCurrentPositionToRegister(2, kLabel);
+ m.Succeed();
+ m.BindJumpTarget(&on_backtrack);
+ m.WriteCurrentPositionToRegister(2, kBacktrack);
+ m.Succeed();
+
+ DirectHandle<String> source = factory->NewStringFromStaticChars("....");
+ DirectHandle<Object> code_object =
+ m.GetCode(CreateRegExpData(i_isolate(), source), {});
+ DirectHandle<Code> code = TrustedCast<Code>(code_object);
+ DirectHandle<JSRegExp> regexp = CreateJSRegExp(source, code);
+
+ struct {
+ const char* input;
+ int exit;
+ } cases[] = {
+ // 'a' (0x61) has bit 7 clear and bit 0 set, 'B' (0x42) has bit 6 set and
+ // bit 5 clear, and no character has bit 7 set.
+ {"aBcD", kMatched},
+ {"aBc\xC4", kLabel}, // Bit 31 of the word set.
+ {"a\xC2"
+ "cD",
+ kBacktrack}, // Bit 15 of the half-word set.
+ {"\xE1"
+ "BcD",
+ kBacktrack}, // Bit 7 of the first character set.
+ {"bBcD", kLabel}, // Bit 0 of the first character clear.
+ {"a\x02"
+ "cD",
+ kBacktrack}, // Bit 6 of the second character clear.
+ {"abcD", kLabel}, // Bit 5 of the second character set.
+ };
+ for (const auto& c : cases) {
+ DirectHandle<String> input =
+ factory->NewStringFromOneByte(base::OneByteVector(c.input))
+ .ToHandleChecked();
+ DirectHandle<SeqOneByteString> seq_input = Cast<SeqOneByteString>(input);
+ Address start_adr = seq_input->GetCharsAddress();
+
+ int captures[4] = {42, 37, 87, 117};
+ regexp::NativeRegExpMacroAssembler::Result result = Execute(
+ *regexp, *input, 0, start_adr, start_adr + input->length(), captures);
+
+ CHECK_EQ(regexp::NativeRegExpMacroAssembler::SUCCESS, result);
+ CHECK_EQ(c.exit, captures[2]);
+ CHECK_EQ(c.exit == kMatched ? 0 : -1, captures[0]);
+ CHECK_EQ(c.exit == kMatched ? 4 : -1, captures[1]);
+ CHECK_EQ(-1, captures[3]);
+ }
+}
+
TEST_F(RegExpTest, MacroAssemblerNativeBackReferenceLATIN1) {
ContextInitializer initializer;
Factory* factory = i_isolate()->factory();
@@ -1373,6 +1469,72 @@ TEST_F(RegExpTest, MacroAssembler) {
}
}
+#ifdef V8_INTL_SUPPORT
+#ifndef DEBUG
+namespace {
+
+UChar32 CanonicalizeNonUnicodeForTest(UChar32 c) {
+ icu::UnicodeString upper(c);
+ upper.toUpper(icu::Locale::getRoot());
+ if (upper.length() != 1) return c;
+ UChar32 result = upper.charAt(0);
+ return c >= 128 && result < 128 ? c : result;
+}
+
+} // namespace
+
+TEST_F(RegExpTest, NonUnicodeCaseEquivalence) {
+ using CaseFolding = regexp::CaseFolding;
+ std::vector<UChar32> canonical(0x10000);
+ std::vector<std::vector<UChar32>> classes(0x10000);
+ for (UChar32 c = 0; c <= 0xffff; ++c) {
+ canonical[c] = CanonicalizeNonUnicodeForTest(c);
+ classes[canonical[c]].push_back(c);
+ }
+ std::vector<UChar32> canonical_to_key(0x10000, -1);
+ std::vector<UChar32> key_to_canonical(0x10000, -1);
+ for (UChar32 c = 0; c <= 0xffff; ++c) {
+ UChar32 key =
+ CaseFolding::EquivalenceKey(c, CaseFolding::Mode::kNonUnicode);
+ ASSERT_GE(key, 0);
+ ASSERT_LE(key, 0xffff);
+ if (canonical_to_key[canonical[c]] == -1) {
+ canonical_to_key[canonical[c]] = key;
+ }
+ if (key_to_canonical[key] == -1) key_to_canonical[key] = canonical[c];
+ ASSERT_EQ(canonical_to_key[canonical[c]], key) << c;
+ ASSERT_EQ(key_to_canonical[key], canonical[c]) << c;
+
+ icu::UnicodeSet expected;
+ for (UChar32 member : classes[canonical[c]]) expected.add(member);
+ icu::UnicodeSet actual(c, c);
+ CaseFolding::CloseOver(actual, CaseFolding::Mode::kNonUnicode);
+ ASSERT_TRUE(expected == actual) << c;
+ }
+}
+#endif // !DEBUG
+
+TEST_F(RegExpTest, CaseClosureMixedSets) {
+ using CaseFolding = regexp::CaseFolding;
+ for (auto mode :
+ {CaseFolding::Mode::kNonUnicode, CaseFolding::Mode::kUnicode}) {
+ icu::UnicodeSet actual;
+ actual.add('a', 'c').add('k').add(0x017f).add(0x00df);
+ icu::UnicodeSet expected(actual);
+ expected.add('A', 'C').add('K');
+ if (mode == CaseFolding::Mode::kUnicode) {
+ expected.add('s').add('S').add(0x212a).add(0x1e9e);
+ actual.add(0x10400);
+ expected.add(0x10400).add(0x10428);
+ }
+ CaseFolding::CloseOver(actual, mode);
+ EXPECT_TRUE(expected == actual);
+ CaseFolding::CloseOver(actual, mode);
+ EXPECT_TRUE(expected == actual);
+ }
+}
+#endif // V8_INTL_SUPPORT
+
#ifndef V8_INTL_SUPPORT
static base::uc32 canonicalize(base::uc32 c) {
unibrow::uchar canon[unibrow::Ecma262Canonicalize::kMaxWidth];
diff --git a/deps/v8/test/unittests/regress/regress-568831099-unittest.cc b/deps/v8/test/unittests/regress/regress-568831099-unittest.cc
new file mode 100644
index 00000000000..26f523c848f
--- /dev/null
+++ b/deps/v8/test/unittests/regress/regress-568831099-unittest.cc
@@ -0,0 +1,94 @@
+// Copyright 2026 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/api/api-inl.h"
+#include "src/codegen/compiler.h"
+#include "src/execution/isolate-inl.h"
+#include "src/objects/feedback-vector-inl.h"
+#include "src/objects/js-function-inl.h"
+#include "src/objects/script-inl.h"
+#include "src/objects/shared-function-info-inl.h"
+#include "src/parsing/parse-info.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+using Regress568831099Test = TestWithContext;
+
+TEST_F(Regress568831099Test, ReparseFunctionConstructorToplevel) {
+ v8::HandleScope scope(isolate());
+
+ RunJS(
+ "var anonymous = 40;\n"
+ "var fn = new Function('a', 'if (a === 0) { anonymous; a.x } a.s = 1; "
+ "return a.s + anonymous;');\n"
+ "for (var i = 0; i < 20; i++) fn({s: 0});\n");
+
+ v8::Local<v8::Object> global = context()->Global();
+ DirectHandle<JSFunction> fn = Cast<JSFunction>(v8::Utils::OpenDirectHandle(
+ *global->Get(context(), NewString("fn")).ToLocalChecked()));
+
+ Handle<SharedFunctionInfo> inner_sfi(fn->shared(), i_isolate());
+ DirectHandle<Script> script(Cast<Script>(inner_sfi->script()), i_isolate());
+ EXPECT_EQ(script->compilation_kind(),
+ Script::CompilationKind::kFunctionConstructor);
+ EXPECT_EQ(inner_sfi->syntax_kind(), FunctionSyntaxKind::kAnonymousExpression);
+
+ const int expected_slot_count = inner_sfi->feedback_metadata()->slot_count();
+ ASSERT_TRUE(fn->has_feedback_vector());
+ EXPECT_EQ(static_cast<int>(fn->feedback_vector()->length().value()),
+ expected_slot_count);
+
+ Tagged<MaybeObject> maybe_toplevel =
+ script->infos()->get(kFunctionLiteralIdTopLevel);
+ Handle<SharedFunctionInfo> toplevel_sfi(
+ Cast<SharedFunctionInfo>(maybe_toplevel.GetHeapObjectAssumeWeak()),
+ i_isolate());
+ ASSERT_TRUE(toplevel_sfi->is_toplevel());
+
+ // Top-level compiles for kFunctionConstructor scripts must restore the
+ // ONLY_SINGLE_FUNCTION_LITERAL parse restriction, while inner function
+ // compiles must not.
+ UnoptimizedCompileFlags toplevel_flags =
+ UnoptimizedCompileFlags::ForFunctionCompile(i_isolate(), *toplevel_sfi);
+ EXPECT_EQ(toplevel_flags.parse_restriction(), ONLY_SINGLE_FUNCTION_LITERAL);
+
+ UnoptimizedCompileFlags inner_flags =
+ UnoptimizedCompileFlags::ForFunctionCompile(i_isolate(), *inner_sfi);
+ EXPECT_EQ(inner_flags.parse_restriction(), NO_PARSE_RESTRICTION);
+
+ // Exercise source position collection on the top-level SFI while compiled.
+ SharedFunctionInfo::EnsureSourcePositionsAvailable(i_isolate(), toplevel_sfi);
+
+ // Flush bytecode from both the top-level SFI and the inner function SFI,
+ // while `fn` keeps its FeedbackVector.
+ if (toplevel_sfi->CanDiscardCompiled()) {
+ SharedFunctionInfo::DiscardCompiled(i_isolate(), toplevel_sfi);
+ }
+ ASSERT_TRUE(inner_sfi->CanDiscardCompiled());
+ SharedFunctionInfo::DiscardCompiled(i_isolate(), inner_sfi);
+ ASSERT_FALSE(toplevel_sfi->is_compiled());
+ ASSERT_FALSE(inner_sfi->is_compiled());
+
+ // Recompiling the top-level SFI also eagerly recompiles the parenthesized
+ // `(function anonymous(...) { ... })` inner SFI. It must still be parsed as
+ // an anonymous dynamic function declaration rather than a named function
+ // expression.
+ IsCompiledScope is_compiled_scope;
+ SharedFunctionInfo::EnsureBytecodeArrayAvailable(i_isolate(), toplevel_sfi,
+ &is_compiled_scope,
+ CreateSourcePositions{true});
+ EXPECT_TRUE(toplevel_sfi->is_compiled());
+ EXPECT_TRUE(inner_sfi->is_compiled());
+ EXPECT_EQ(inner_sfi->syntax_kind(), FunctionSyntaxKind::kAnonymousExpression);
+ EXPECT_EQ(inner_sfi->feedback_metadata()->slot_count(), expected_slot_count);
+
+ v8::Local<v8::Value> result = RunJS("fn({s: 0})");
+ EXPECT_EQ(result->Int32Value(context()).FromJust(), 41);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc b/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc
index 66846793a19..6f726415a5a 100644
--- a/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc
+++ b/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc
@@ -233,16 +233,34 @@ TEST_F(GeneratedCodeValidatorTest, ValidateRootRegisterPartialInitFails) {
TEST_F(GeneratedCodeValidatorTest, ValidateSystemRegisterWrites) {
Isolate* i_isolate = this->i_isolate();
- auto buffer = AllocateAssemblerBuffer();
- MacroAssembler masm(i_isolate, CodeObjectRequired{false},
- buffer->CreateView());
+ {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
- // Writing to system register should fail validation.
- __ Msr(NZCV, x0);
- __ ret();
+ // Writing to system register should fail validation.
+ __ Msr(NZCV, x0);
+ __ ret();
- CheckValidationFails(i_isolate, masm,
- "Instruction writes to prohibited system registers");
+ CheckValidationFails(i_isolate, masm,
+ "Instruction writes to prohibited system registers");
+ }
+
+ {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+ // Raw ARM64 encoding for `msr daifset, #2` (opcode 0xd50342df)
+ __ db(0xdf);
+ __ db(0x42);
+ __ db(0x03);
+ __ db(0xd5);
+ __ ret();
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction writes to prohibited system registers");
+ }
}
#endif // V8_TARGET_ARCH_ARM64
diff --git a/deps/v8/test/unittests/sandbox/sandbox-crash-filter-unittest.cc b/deps/v8/test/unittests/sandbox/sandbox-crash-filter-unittest.cc
index efb38b7d5fb..9d2d903cba4 100644
--- a/deps/v8/test/unittests/sandbox/sandbox-crash-filter-unittest.cc
+++ b/deps/v8/test/unittests/sandbox/sandbox-crash-filter-unittest.cc
@@ -2,13 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include <cstring>
+#include <memory>
+#include "include/v8-platform.h"
+#include "src/sandbox/sandbox.h"
#include "src/sandbox/testing.h"
#include "test/unittests/test-utils.h"
+#if defined(V8_USE_ADDRESS_SANITIZER)
+#include <sanitizer/asan_interface.h>
+#endif
+
+#ifdef V8_OS_LINUX
+#include <sys/mman.h>
+#include <unistd.h>
+#undef MAP_TYPE
+#endif
+
#ifdef V8_ENABLE_SANDBOX
namespace v8 {
@@ -22,9 +36,9 @@ using SandboxCrashFilterTest = TestWithIsolate;
// or non-canonical pointers (e.g., 52-bit addresses on 48-bit systems) as
// harmless.
TEST_F(SandboxCrashFilterTest, SandboxCrashFilterUnaddressableAccess) {
- SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
ASSERT_EXIT(
{
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
volatile char* p = reinterpret_cast<volatile char*>(1ULL << 62);
char c = *p; // Trigger fault
(void)c;
@@ -34,13 +48,36 @@ TEST_F(SandboxCrashFilterTest, SandboxCrashFilterUnaddressableAccess) {
#ifdef V8_USE_ADDRESS_SANITIZER
+// Verifies that a crash on an unknown address is treated as a sandbox
+// violation, and that the ASan crash filter does not contradict this
+// classification (by e.g. ignoring it as a null address).
+TEST_F(SandboxCrashFilterTest, UnmappedMemoryViolation) {
+ EXPECT_EXIT(
+ {
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
+ // Allocate a page and immediately free it to guarantee an unmapped
+ // address without relying on hardcoded constants.
+ size_t page_size = sysconf(_SC_PAGESIZE);
+ void* dest = mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ CHECK(dest != MAP_FAILED);
+ munmap(dest, page_size);
+
+ volatile char* p = reinterpret_cast<volatile char*>(dest);
+ *p = 42;
+ },
+ testing::ExitedWithCode(1),
+ testing::AllOf(testing::HasSubstr("V8 sandbox violation detected!"),
+ testing::Not(testing::HasSubstr(
+ "Caught ASan fault without a fault address"))));
+}
+
// Verifies that a memcpy strictly contained within the sandbox is safely
// ignored.
//
// NOTE: The test may potentially start failing after a Clang roll, if the
// compiler optimizes away the memcpy.
TEST_F(SandboxCrashFilterTest, OverlappingMemcpyInsideSandbox) {
- SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
Sandbox* sandbox = Sandbox::current();
Address addr = sandbox->base() + 0x100000; // Somewhere in the sandbox
@@ -48,8 +85,14 @@ TEST_F(SandboxCrashFilterTest, OverlappingMemcpyInsideSandbox) {
void* dest = reinterpret_cast<void*>(addr + 1);
EXPECT_EXIT(
- { memcpy(dest, src, 10); }, testing::ExitedWithCode(0),
- ".*harmless ASan fault.*");
+ {
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
+ memcpy(dest, src, 10);
+ },
+ testing::ExitedWithCode(0),
+ testing::AllOf(
+ testing::HasSubstr("AddressSanitizer: memcpy-param-overlap"),
+ testing::HasSubstr("harmless ASan fault")));
}
// Verifies that an overlapping memcpy completely outside the sandbox (e.g. on
@@ -59,20 +102,112 @@ TEST_F(SandboxCrashFilterTest, OverlappingMemcpyInsideSandbox) {
// compiler optimizes away the memcpy. We use a volatile read to attempt to
// prevent this.
TEST_F(SandboxCrashFilterTest, OverlappingMemcpyOutsideSandbox) {
- SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
char buffer[100] = {1};
void* src = buffer;
void* dest = buffer + 1;
EXPECT_EXIT(
{
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
memcpy(dest, src, 10);
volatile char escape = buffer[1];
(void)escape;
},
- testing::ExitedWithCode(1), ".*V8 sandbox violation detected!.*");
+ testing::ExitedWithCode(1),
+ testing::AllOf(
+ testing::HasSubstr("AddressSanitizer: memcpy-param-overlap"),
+ testing::HasSubstr("V8 sandbox violation detected!")));
}
+// Verifies that an ASan fault on the C++ heap (outside the sandbox) triggers
+// the violation.
+//
+// NOTE: The test may potentially start failing after a Clang roll, if the
+// compiler optimizes away the memory access. We use a volatile read to attempt
+// to prevent this.
+TEST_F(SandboxCrashFilterTest, ASanUseAfterPoison) {
+ constexpr size_t kBufferSize = 128;
+
+ std::unique_ptr<char[]> buffer(new char[kBufferSize]);
+
+ EXPECT_EXIT(
+ {
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
+ __asan_poison_memory_region(buffer.get(), kBufferSize);
+
+ volatile char* p = reinterpret_cast<volatile char*>(buffer.get());
+ char c = *p;
+ (void)c;
+ },
+ testing::ExitedWithCode(1),
+ testing::AllOf(testing::HasSubstr("AddressSanitizer: use-after-poison"),
+ testing::HasSubstr("V8 sandbox violation detected!")));
+}
+
+#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
+
+// Verifies that an ASan fault inside a region registered as safe is safely
+// ignored by the crash filter.
+//
+// NOTE: The test may potentially start failing after a Clang roll, if the
+// compiler optimizes away the memory access. We use a volatile read to attempt
+// to prevent this.
+TEST_F(SandboxCrashFilterTest, ASanUseAfterPoisonInSafeRegion) {
+ constexpr size_t kBufferSize = 128;
+
+ std::unique_ptr<char[]> buffer(new char[kBufferSize]);
+
+ SandboxTesting::RegisterSafeMemoryRegion(
+ reinterpret_cast<Address>(buffer.get()), kBufferSize,
+ SandboxTesting::kReadAndWriteAccessIsSafe);
+
+ EXPECT_EXIT(
+ {
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
+ __asan_poison_memory_region(buffer.get(), kBufferSize);
+
+ volatile char* p = reinterpret_cast<volatile char*>(buffer.get());
+ char c = *p;
+ (void)c;
+ },
+ testing::ExitedWithCode(0),
+ testing::AllOf(testing::HasSubstr("AddressSanitizer: use-after-poison"),
+ testing::HasSubstr("harmless ASan fault")));
+}
+
+// Verifies that an ASan fault inside the sandbox address space is safely
+// ignored by the crash filter.
+//
+// NOTE: The test may potentially start failing after a Clang roll, if the
+// compiler optimizes away the memory access. We use a volatile read to attempt
+// to prevent this.
+TEST_F(SandboxCrashFilterTest, ASanUseAfterPoisonInsideSandbox) {
+ Sandbox* sandbox = Sandbox::current();
+
+ v8::PageAllocator* allocator = sandbox->page_allocator();
+ size_t size = allocator->AllocatePageSize();
+ void* dest = allocator->AllocatePages(nullptr, size, size,
+ v8::PageAllocator::kReadWrite);
+ CHECK_NOT_NULL(dest);
+
+ EXPECT_EXIT(
+ {
+ SandboxTesting::Enable(SandboxTesting::Mode::kForTesting);
+ __asan_poison_memory_region(dest, 10);
+
+ volatile char* p = reinterpret_cast<volatile char*>(dest);
+ char c = *p;
+ (void)c;
+ },
+ testing::ExitedWithCode(0),
+ testing::AllOf(testing::HasSubstr("AddressSanitizer: use-after-poison"),
+ testing::HasSubstr("harmless ASan fault")));
+
+ allocator->FreePages(dest, size);
+}
+
+#endif // V8_ENABLE_MEMORY_CORRUPTION_API
+
#endif // V8_USE_ADDRESS_SANITIZER
#endif // V8_OS_LINUX
diff --git a/deps/v8/test/unittests/test-helpers.cc b/deps/v8/test/unittests/test-helpers.cc
index 8a691051f38..fce1b695ac2 100644
--- a/deps/v8/test/unittests/test-helpers.cc
+++ b/deps/v8/test/unittests/test-helpers.cc
@@ -47,9 +47,6 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
shared->set_uncompiled_data(
*isolate->factory()->NewUncompiledDataWithoutPreparseDataWithJob(
isolate->factory()->empty_string(), 0, source->length()));
- // Make sure we have an outer scope info, even though it's empty
- shared->set_raw_outer_scope_info_or_feedback_metadata(
- ScopeInfo::Empty(isolate));
shared->SetScript(isolate, ReadOnlyRoots(isolate), *script,
function_literal_id);
return scope.CloseAndEscape(shared);
diff --git a/deps/v8/test/unittests/test-utils.h b/deps/v8/test/unittests/test-utils.h
index 57cef05a3cb..720e244aae6 100644
--- a/deps/v8/test/unittests/test-utils.h
+++ b/deps/v8/test/unittests/test-utils.h
@@ -46,8 +46,13 @@ static v8::Local<v8::External> MakeData(v8::Isolate* isolate, void* pointer) {
template <typename T, typename TCallbackInfo>
static T* GetData(const TCallbackInfo& info) {
USE(MakeData);
- return reinterpret_cast<T*>(
- v8::External::Cast(*info.Data())->Value(kTestConfigTag));
+ v8::Local<v8::Data> data;
+ if constexpr (requires { info.DataV2(); }) {
+ data = info.DataV2();
+ } else {
+ data = info.Data();
+ }
+ return reinterpret_cast<T*>(v8::External::Cast(*data)->Value(kTestConfigTag));
}
class ArrayBufferAllocator;
diff --git a/deps/v8/test/unittests/utils/version-unittest.cc b/deps/v8/test/unittests/utils/version-unittest.cc
index 75f72464285..28415a090a4 100644
--- a/deps/v8/test/unittests/utils/version-unittest.cc
+++ b/deps/v8/test/unittests/utils/version-unittest.cc
@@ -93,5 +93,22 @@ TEST_F(VersionTest, VersionString) {
"libv8-6.0.287.53-emb.1-candidate.so");
}
+TEST_F(VersionTest, VersionHash) {
+ SetVersion(1, 2, 3, 4, "", false, "");
+ uint32_t default_hash = static_cast<uint32_t>(base::hash_combine(1, 2, 3, 4));
+ EXPECT_EQ(default_hash, Version::Hash());
+
+ SetVersion(1, 2, 3, 4, "-emb.1", false, "");
+ uint32_t embedder_hash = Version::Hash();
+ EXPECT_NE(default_hash, embedder_hash);
+
+ char equivalent_embedder[] = "-emb.1";
+ SetVersion(1, 2, 3, 4, equivalent_embedder, false, "");
+ EXPECT_EQ(embedder_hash, Version::Hash());
+
+ SetVersion(1, 2, 3, 4, "-emb.2", false, "");
+ EXPECT_NE(embedder_hash, Version::Hash());
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/wasm/liftoff-register-unittests.cc b/deps/v8/test/unittests/wasm/liftoff-register-unittests.cc
index 66c956d4322..9aa33ab9fc0 100644
--- a/deps/v8/test/unittests/wasm/liftoff-register-unittests.cc
+++ b/deps/v8/test/unittests/wasm/liftoff-register-unittests.cc
@@ -3,10 +3,15 @@
// found in the LICENSE file.
#include "src/wasm/baseline/liftoff-assembler-defs.h"
-#if V8_TARGET_ARCH_IA32
-#include "src/execution/ia32/frame-constants-ia32.h"
-#elif V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64
+#include "src/codegen/safepoint-table.h"
#include "src/execution/x64/frame-constants-x64.h"
+#include "src/wasm/baseline/liftoff-assembler-inl.h"
+#include "test/common/assembler-tester.h"
+#include "test/common/flag-utils.h"
+#include "test/unittests/test-utils.h"
+#elif V8_TARGET_ARCH_IA32
+#include "src/execution/ia32/frame-constants-ia32.h"
#elif V8_TARGET_ARCH_MIPS64
#include "src/execution/mips64/frame-constants-mips64.h"
#elif V8_TARGET_ARCH_LOONG64
@@ -73,6 +78,71 @@ TEST_F(WasmRegisterTest, SpreadSetBitsToAdjacentFpRegs) {
EXPECT_EQ(expected, actual);
}
+#if V8_TARGET_ARCH_X64
+using LiftoffFrameAlignmentTest = TestWithIsolateAndZone;
+
+TEST_F(LiftoffFrameAlignmentTest, AlignFrameSizeAndPatchPrepareStackFrame) {
+ auto check_frame_alignment = [&](bool enforce_16byte_alignment,
+ bool feedback_vector_slot,
+ int used_spill_offset) {
+ FlagScope<bool> flag_scope(&v8_flags.enforce_x64_16byte_alignment,
+ enforce_16byte_alignment);
+
+ auto buffer = AllocateAssemblerBuffer();
+ LiftoffAssembler assm(zone(), buffer->CreateView());
+ assm.set_root_array_available(false);
+ SafepointTableBuilder safepoint_table_builder(zone());
+
+ // Set up the fixed header slots below rbp the same way Liftoff does:
+ // - Without feedback_vector_slot: EnterFrame(StackFrame::WASM) pushes 2
+ // slots (frame type marker and instance data).
+ // - With feedback_vector_slot: WasmLiftoffFrameSetup pushes 3 slots (frame
+ // type marker, instance data, and feedback vector).
+ assm.EnterFrame(StackFrame::WASM);
+ if (feedback_vector_slot) {
+ assm.Push(Immediate(0));
+ }
+
+ int prepare_offset = assm.PrepareStackFrame();
+ assm.RecordUsedSpillOffset(used_spill_offset);
+ assm.AlignFrameSize();
+ assm.PatchPrepareStackFrame(prepare_offset, &safepoint_table_builder,
+ feedback_vector_slot, /*stack_param_slots=*/0);
+
+ assm.movq(rax, rbp);
+ assm.subq(rax, rsp);
+ assm.LeaveFrame(StackFrame::WASM);
+ assm.ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(isolate(), &desc);
+ buffer->MakeExecutable();
+ auto fn = GeneratedCode<int64_t>::FromBuffer(isolate(), buffer->start());
+ int64_t allocated_bytes_below_rbp = fn.Call();
+
+ EXPECT_EQ(allocated_bytes_below_rbp, assm.GetTotalFrameSize());
+ if (enforce_16byte_alignment) {
+ int expected_bytes = RoundUp(used_spill_offset, 2 * kSystemPointerSize);
+ EXPECT_EQ(expected_bytes, assm.GetTotalFrameSize());
+ EXPECT_EQ(0, allocated_bytes_below_rbp % (2 * kSystemPointerSize));
+ } else {
+ int expected_bytes = RoundUp(used_spill_offset, kSystemPointerSize);
+ EXPECT_EQ(expected_bytes, assm.GetTotalFrameSize());
+ }
+ };
+
+ // Test spill offsets spanning even, odd, and sub-slot (4-byte) boundaries:
+ // 32 bytes (4 slots), 36 bytes (4.5 slots), 40 bytes (5 slots, odd),
+ // 44 bytes (5.5 slots), 48 bytes (6 slots, even).
+ for (bool feedback_vector_slot : {false, true}) {
+ for (int spill_offset : {32, 36, 40, 44, 48}) {
+ check_frame_alignment(false, feedback_vector_slot, spill_offset);
+ check_frame_alignment(true, feedback_vector_slot, spill_offset);
+ }
+ }
+}
+#endif // V8_TARGET_ARCH_X64
+
} // namespace wasm
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/wasm/simd-cross-compiler-determinism-fuzztest.cc b/deps/v8/test/unittests/wasm/simd-cross-compiler-determinism-fuzztest.cc
index 971819a5132..3e9da1115c6 100644
--- a/deps/v8/test/unittests/wasm/simd-cross-compiler-determinism-fuzztest.cc
+++ b/deps/v8/test/unittests/wasm/simd-cross-compiler-determinism-fuzztest.cc
@@ -37,12 +37,19 @@ struct FuzzExtMulPairwiseTree {
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
struct AVXSupport {
- bool previous_;
- explicit AVXSupport(bool allow) : previous_(CpuFeatures::IsSupported(AVX)) {
- if (!allow) CpuFeatures::SetUnsupported(AVX);
+ bool previous_avx_;
+ bool previous_fma3_;
+ explicit AVXSupport(bool allow)
+ : previous_avx_(CpuFeatures::IsSupported(AVX)),
+ previous_fma3_(CpuFeatures::IsSupported(FMA3)) {
+ if (!allow) {
+ CpuFeatures::SetUnsupported(AVX);
+ CpuFeatures::SetUnsupported(FMA3);
+ }
}
~AVXSupport() {
- if (previous_) CpuFeatures::SetSupported(AVX);
+ if (previous_avx_) CpuFeatures::SetSupported(AVX);
+ if (previous_fma3_) CpuFeatures::SetSupported(FMA3);
}
};
#endif // V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
@@ -57,7 +64,7 @@ class SimdCrossCompilerDeterminismTest
void TestTernOp(WasmOpcode opcode, std::array<Simd128, 3> inputs,
int preconsumed_liftoff_regs, bool allow_avx);
- void TestShuffleTree(WasmOpcode binop, WasmOpcode unop,
+ void TestShuffleTree(WasmOpcode binop, WasmOpcode unop, WasmOpcode ternop,
std::array<Simd128, 4> inputs,
std::array<uint8_t, kSimd128Size> shuffle0,
std::array<uint8_t, kSimd128Size> shuffle1,
@@ -159,7 +166,8 @@ class SimdCrossCompilerDeterminismTest
// Test shuffle patterns.
template <typename Config>
Simd128 GetShuffleTreeResult(TestExecutionTier tier, WasmOpcode binop,
- WasmOpcode unop, std::array<Simd128, 4> inputs,
+ WasmOpcode unop, WasmOpcode ternop,
+ std::array<Simd128, 4> inputs,
std::array<uint8_t, kSimd128Size> shuffle0,
std::array<uint8_t, kSimd128Size> shuffle1,
std::array<uint8_t, kSimd128Size> shuffle2,
@@ -172,6 +180,11 @@ class SimdCrossCompilerDeterminismTest
CommonWasmRunner<void> runner(isolate(), tier);
Simd128* memory = runner.builder().AddMemoryElems<Simd128>(8);
+ uint8_t locals_start = runner.AllocateLocals(6, kWasmS128);
+ auto locals_idx = [locals_start](uint8_t offset) -> uint8_t {
+ return static_cast<uint8_t>(locals_start + offset);
+ };
+
// Build the bytecode.
// Note: `kMaxBytecodeSize` is just big enough to hold all bytes we generate
// below across all configuration. If the DCHECK below fails, increase it as
@@ -187,9 +200,6 @@ class SimdCrossCompilerDeterminismTest
bytecode.insert(bytecode.end(), {WASM_SIMD_CONSTANT(Simd128{}.bytes())});
}
- // Push the memory index for the final store.
- bytecode.insert(bytecode.end(), {WASM_ZERO});
-
// x0 = shuffle(a, b)
bytecode.insert(bytecode.end(),
Config::template GetInput<0>(memory, inputs[0]));
@@ -197,6 +207,7 @@ class SimdCrossCompilerDeterminismTest
Config::template GetInput<1>(memory, inputs[1]));
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
bytecode.insert(bytecode.end(), shuffle0.begin(), shuffle0.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(0)});
// y0 = shuffle(c, d)
bytecode.insert(bytecode.end(),
@@ -205,10 +216,27 @@ class SimdCrossCompilerDeterminismTest
Config::template GetInput<3>(memory, inputs[3]));
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
bytecode.insert(bytecode.end(), shuffle1.begin(), shuffle1.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(1)});
+
+ auto emit_pass_thru = [&](uint8_t left, uint8_t right) {
+ // Add unary, binary, and ternary s128->s128 operations between shuffle
+ // levels. When these are pass-through operations, the shuffle reducer's
+ // demanded-byte analysis should be able to continue through them.
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(left)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(unop)});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(left)});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(right)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(binop)});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(right)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(ternop)});
+ };
// z0 = shuffle(x0, y0)
+ emit_pass_thru(0, 1);
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(1)});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
bytecode.insert(bytecode.end(), shuffle2.begin(), shuffle2.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(2)});
// x1 = shuffle(b, c)
bytecode.insert(bytecode.end(),
@@ -216,7 +244,8 @@ class SimdCrossCompilerDeterminismTest
bytecode.insert(bytecode.end(),
Config::template GetInput<2>(memory, inputs[2]));
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
- bytecode.insert(bytecode.end(), shuffle0.begin(), shuffle0.end());
+ bytecode.insert(bytecode.end(), shuffle3.begin(), shuffle3.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(3)});
// y1 = shuffle(d, a)
bytecode.insert(bytecode.end(),
@@ -224,13 +253,22 @@ class SimdCrossCompilerDeterminismTest
bytecode.insert(bytecode.end(),
Config::template GetInput<0>(memory, inputs[0]));
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
- bytecode.insert(bytecode.end(), shuffle1.begin(), shuffle1.end());
+ bytecode.insert(bytecode.end(), shuffle4.begin(), shuffle4.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(4)});
// z1 = shuffle(x1, y1)
+ emit_pass_thru(3, 4);
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(4)});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI8x16Shuffle)});
bytecode.insert(bytecode.end(), shuffle5.begin(), shuffle5.end());
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(5)});
+
+ // Push the memory index for the final store.
+ bytecode.insert(bytecode.end(), {WASM_ZERO});
// unop(binop(z0, z1));
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(2)});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(5)});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(binop)});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(unop)});
@@ -756,8 +794,8 @@ V8_FUZZ_TEST_F(SimdCrossCompilerDeterminismTest, TestExtMulPairwiseTree)
fuzztest::Arbitrary<bool>());
void SimdCrossCompilerDeterminismTest::TestShuffleTree(
- WasmOpcode binop, WasmOpcode unop, std::array<Simd128, 4> inputs,
- std::array<uint8_t, kSimd128Size> shuffle0,
+ WasmOpcode binop, WasmOpcode unop, WasmOpcode ternop,
+ std::array<Simd128, 4> inputs, std::array<uint8_t, kSimd128Size> shuffle0,
std::array<uint8_t, kSimd128Size> shuffle1,
std::array<uint8_t, kSimd128Size> shuffle2,
std::array<uint8_t, kSimd128Size> shuffle3,
@@ -774,30 +812,35 @@ void SimdCrossCompilerDeterminismTest::TestShuffleTree(
// one Liftoff mode (but with a dynamic amount of preconsumed registers).
GetShuffleTreeResult<
InputLocations<kConstant, kConstant, kConstant, kConstant>>(
- TestExecutionTier::kLiftoff, binop, unop, inputs, shuffle0, shuffle1,
- shuffle2, shuffle3, shuffle4, shuffle5, preconsumed_liftoff_regs),
+ TestExecutionTier::kLiftoff, binop, unop, ternop, inputs, shuffle0,
+ shuffle1, shuffle2, shuffle3, shuffle4, shuffle5,
+ preconsumed_liftoff_regs),
// Different Turbofan configs, embedding inputs as constants or having
// dynamic inputs.
// - input constant
GetShuffleTreeResult<
InputLocations<kConstant, kConstant, kConstant, kConstant>>(
- TestExecutionTier::kTurbofan, binop, unop, inputs, shuffle0, shuffle1,
- shuffle2, shuffle3, shuffle4, shuffle5),
+ TestExecutionTier::kTurbofan, binop, unop, ternop, inputs, shuffle0,
+ shuffle1, shuffle2, shuffle3, shuffle4, shuffle5),
// - input dynamic
GetShuffleTreeResult<
InputLocations<kDynamic, kDynamic, kDynamic, kDynamic, kDynamic>>(
- TestExecutionTier::kTurbofan, binop, unop, inputs, shuffle0, shuffle1,
- shuffle2, shuffle3, shuffle4, shuffle5)};
+ TestExecutionTier::kTurbofan, binop, unop, ternop, inputs, shuffle0,
+ shuffle1, shuffle2, shuffle3, shuffle4, shuffle5)};
ASSERT_TRUE(AllResultsEqual<Simd128>(base::VectorOf(results)))
- << absl::StrFormat("Shuffles: %v, %v, %v, %v, %vand %v\n",
- *reinterpret_cast<Simd128*>(shuffle0.data()),
- *reinterpret_cast<Simd128*>(shuffle1.data()),
- *reinterpret_cast<Simd128*>(shuffle2.data()),
- *reinterpret_cast<Simd128*>(shuffle3.data()),
- *reinterpret_cast<Simd128*>(shuffle4.data()),
- *reinterpret_cast<Simd128*>(shuffle5.data()))
+ << absl::StrFormat(
+ "Operations: %s, %s, %s\n"
+ "Shuffles: %v, %v, %v, %v, %v and %v\n",
+ WasmOpcodes::OpcodeName(binop), WasmOpcodes::OpcodeName(unop),
+ WasmOpcodes::OpcodeName(ternop),
+ *reinterpret_cast<Simd128*>(shuffle0.data()),
+ *reinterpret_cast<Simd128*>(shuffle1.data()),
+ *reinterpret_cast<Simd128*>(shuffle2.data()),
+ *reinterpret_cast<Simd128*>(shuffle3.data()),
+ *reinterpret_cast<Simd128*>(shuffle4.data()),
+ *reinterpret_cast<Simd128*>(shuffle5.data()))
<< "Different results for different configs: "
<< PrintCollection(base::VectorOf(results));
}
@@ -981,6 +1024,8 @@ V8_FUZZ_TEST_F(SimdCrossCompilerDeterminismTest, TestShuffleTree)
fuzztest::ElementOf<WasmOpcode>(kBinOps),
// unop
fuzztest::ElementOf<WasmOpcode>(kUnOps),
+ // ternop
+ fuzztest::ElementOf<WasmOpcode>(kTernOps),
// inputs
fuzztest::ArrayOf<4>(ArbitrarySimd()),
// shuffle 0
diff --git a/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc b/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
index 0dbf961f3a2..4ce6e40740c 100644
--- a/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
+++ b/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
@@ -7,6 +7,7 @@
#include "src/codegen/machine-type.h"
#include "src/codegen/signature.h"
#include "src/compiler/linkage.h"
+#include "src/compiler/wasm-compiler-definitions.h"
#include "src/wasm/value-type.h"
#include "src/wasm/wasm-linkage.h"
#include "test/unittests/test-utils.h"
@@ -111,6 +112,39 @@ TEST_F(WasmCallDescriptorTest, Regress_1174500) {
#endif
}
+TEST(WasmTypeCheckConfigTest, EqualityAndHash) {
+ using compiler::kExactMatchLastSupertype;
+ using compiler::kExactMatchOnly;
+ using compiler::kMayBeSubtype;
+ using compiler::WasmTypeCheckConfig;
+
+ WasmTypeCheckConfig c1{kWasmAnyRef, kWasmFuncRef, kMayBeSubtype};
+ WasmTypeCheckConfig c2{kWasmAnyRef, kWasmFuncRef, kMayBeSubtype};
+ WasmTypeCheckConfig c_diff_from{kWasmExternRef, kWasmFuncRef, kMayBeSubtype};
+ WasmTypeCheckConfig c_diff_to{kWasmAnyRef, kWasmEqRef, kMayBeSubtype};
+ WasmTypeCheckConfig c_diff_exact1{kWasmAnyRef, kWasmFuncRef, kExactMatchOnly};
+ WasmTypeCheckConfig c_diff_exact2{kWasmAnyRef, kWasmFuncRef,
+ kExactMatchLastSupertype};
+
+ EXPECT_EQ(c1, c2);
+ EXPECT_EQ(hash_value(c1), hash_value(c2));
+
+ EXPECT_NE(c1, c_diff_from);
+ EXPECT_NE(hash_value(c1), hash_value(c_diff_from));
+
+ EXPECT_NE(c1, c_diff_to);
+ EXPECT_NE(hash_value(c1), hash_value(c_diff_to));
+
+ EXPECT_NE(c1, c_diff_exact1);
+ EXPECT_NE(hash_value(c1), hash_value(c_diff_exact1));
+
+ EXPECT_NE(c1, c_diff_exact2);
+ EXPECT_NE(hash_value(c1), hash_value(c_diff_exact2));
+
+ EXPECT_NE(c_diff_exact1, c_diff_exact2);
+ EXPECT_NE(hash_value(c_diff_exact1), hash_value(c_diff_exact2));
+}
+
} // namespace wasm
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wasm.inc b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wasm.inc
new file mode 100644
index 00000000000..a2cb661b44b
--- /dev/null
+++ b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wasm.inc
@@ -0,0 +1,53 @@
+ 0x00, 0x61, 0x73, 0x6d, // wasm magic
+ 0x01, 0x00, 0x00, 0x00, // wasm version
+
+ 0x01, // section kind: Type
+ 0x09, // section length 9
+ 0x02, // types count 2
+ 0x60, // kind: func
+ 0x00, // param count 0
+ 0x01, 0x7d, // return count 1: f32
+ 0x60, // kind: func
+ 0x01, 0x7d, // param count 1: f32
+ 0x00, // return count 0
+
+ 0x03, // section kind: Function
+ 0x03, // section length 3
+ 0x02, // functions count 2
+ 0x00, // 0 $func0 (result f32)
+ 0x01, // 1 $func1 (param f32)
+
+ 0x05, // section kind: Memory
+ 0x04, // section length 4
+ 0x01, 0x01, // memory count 1: with maximum
+ 0x01, // initial size 1
+ 0x01, // maximum size 1
+
+ 0x0a, // section kind: Code
+ 0x33, // section length 51
+ 0x02, // functions count 2
+ // function #0 $func0
+ 0x16, // body size 22
+ 0x00, // 0 entries in locals list
+ 0x41, 0x00, // i32.const 0
+ 0xfc, 0x30, 0x01, 0x00, // f32.load_f16
+ 0x41, 0x00, // i32.const 0
+ 0xfc, 0x30, 0x01, 0x04, // f32.load_f16 offset=4
+ 0x92, // f32.add
+ 0x41, 0x00, // i32.const 0
+ 0xfc, 0x30, 0x00, 0x00, // f32.load_f16 align=1
+ 0x92, // f32.add
+ 0x0b, // end
+ // function #1 $func1
+ 0x1a, // body size 26
+ 0x00, // 0 entries in locals list
+ 0x41, 0x00, // i32.const 0
+ 0x20, 0x00, // local.get $var0
+ 0xfc, 0x31, 0x01, 0x00, // f32.store_f16
+ 0x41, 0x00, // i32.const 0
+ 0x20, 0x00, // local.get $var0
+ 0xfc, 0x31, 0x01, 0x04, // f32.store_f16 offset=4
+ 0x41, 0x00, // i32.const 0
+ 0x20, 0x00, // local.get $var0
+ 0xfc, 0x31, 0x00, 0x00, // f32.store_f16 align=1
+ 0x0b, // end
diff --git a/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wat.inc b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wat.inc
new file mode 100644
index 00000000000..76e605df99a
--- /dev/null
+++ b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest-fp16.wat.inc
@@ -0,0 +1,27 @@
+;; expected = R"---(;; This is a polyglot C++/WAT file.
+;; Comment lines are ignored and not expected in the disassembler output.
+(module
+ (memory $memory0 1 1)
+ (func $func0 (result f32)
+ i32.const 0
+ f32.load_f16
+ i32.const 0
+ f32.load_f16 offset=4
+ f32.add
+ i32.const 0
+ f32.load_f16 align=1
+ f32.add
+ )
+ (func $func1 (param $var0 f32)
+ i32.const 0
+ local.get $var0
+ f32.store_f16
+ i32.const 0
+ local.get $var0
+ f32.store_f16 offset=4
+ i32.const 0
+ local.get $var0
+ f32.store_f16 align=1
+ )
+)
+;;)---";
diff --git a/deps/v8/test/unittests/wasm/wasm-disassembler-unittest.cc b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest.cc
index 247dc839102..e5b7c84f93b 100644
--- a/deps/v8/test/unittests/wasm/wasm-disassembler-unittest.cc
+++ b/deps/v8/test/unittests/wasm/wasm-disassembler-unittest.cc
@@ -228,6 +228,46 @@ TEST_F(WasmDisassemblerTest, Atomics) {
CheckDisassemblerOutput(base::ArrayVector(module_bytes), expected);
}
+TEST_F(WasmDisassemblerTest, Fp16) {
+ // This test case was created using:
+ // clang-format off
+ /*
+ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+ let builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1);
+ builder.addFunction(undefined, kSig_f_v)
+ .addBody([
+ kExprI32Const, 0,
+ kNumericPrefix, ...kExprF32LoadF16, 1, 0,
+ kExprI32Const, 0,
+ kNumericPrefix, ...kExprF32LoadF16, 1, 4,
+ kExprF32Add,
+ kExprI32Const, 0,
+ kNumericPrefix, ...kExprF32LoadF16, 0, 0,
+ kExprF32Add,
+ ]);
+ builder.addFunction(undefined, kSig_v_f)
+ .addBody([
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kNumericPrefix, ...kExprF32StoreF16, 1, 0,
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kNumericPrefix, ...kExprF32StoreF16, 1, 4,
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kNumericPrefix, ...kExprF32StoreF16, 0, 0,
+ ]);
+ */
+ // clang-format on
+ constexpr uint8_t module_bytes[] = {
+#include "wasm-disassembler-unittest-fp16.wasm.inc"
+ };
+ std::string expected;
+#include "wasm-disassembler-unittest-fp16.wat.inc"
+ CheckDisassemblerOutput(base::ArrayVector(module_bytes), expected);
+}
+
// TODO(dlehmann): Add tests for the following Wasm features and extensions:
// - custom name section for Wasm GC constructs (struct and array type names,
// struct fields).
diff --git a/deps/v8/third_party/abseil-cpp/README.chromium b/deps/v8/third_party/abseil-cpp/README.chromium
index ff16d9c85b3..f224841baee 100644
--- a/deps/v8/third_party/abseil-cpp/README.chromium
+++ b/deps/v8/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp
License: Apache-2.0
License File: LICENSE
Version: N/A
-Revision: 1c84143fb79e6041f3e0596df51c3ae7d7e46a8a
+Revision: a1b9918b18364077b32a820862c63e14c1edb70b
Update Mechanism: Manual
Security Critical: yes
Shipped: yes
diff --git a/deps/v8/third_party/abseil-cpp/absl/abseil.podspec.gen.py b/deps/v8/third_party/abseil-cpp/absl/abseil.podspec.gen.py
index e19f951193c..73eb9ded270 100755
--- a/deps/v8/third_party/abseil-cpp/absl/abseil.podspec.gen.py
+++ b/deps/v8/third_party/abseil-cpp/absl/abseil.podspec.gen.py
@@ -49,6 +49,7 @@ Pod::Spec.new do |s|
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '4.0'
s.visionos.deployment_target = '1.0'
+ s.exclude_files = [ 'absl/time/internal/cctz/src/*_win.cc' ]
s.subspec 'xcprivacy' do |ss|
ss.resource_bundles = {
ss.module_name => 'PrivacyInfo.xcprivacy',
@@ -189,7 +190,11 @@ def write_podspec_rule(f, rule, depth):
# Since CocoaPods treats header_files a bit differently from bazel,
# this won't generate a header_files field so that all source_files
# are considered as header files.
- srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
+ srcs = [
+ s
+ for s in sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
+ if not s.endswith("_win.cc")
+ ]
write_indented_list(
f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var),
srcs)
diff --git a/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt
index cd7fa221ef7..f062325b004 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt
@@ -49,10 +49,10 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::algorithm
- absl::hardening
absl::config
- absl::iterator_traits_internal
absl::core_headers
+ absl::hardening
+ absl::iterator_traits_internal
absl::meta
PUBLIC
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel
index 969f746dc05..e37b5b48ce8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel
@@ -187,6 +187,7 @@ cc_library(
],
deps = [
":base_internal",
+ ":config",
":core_headers",
":errno_saver",
],
@@ -364,6 +365,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":atomic_hook",
+ ":config",
":core_headers",
],
)
@@ -393,6 +395,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
+ ":config",
":core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -509,6 +512,7 @@ cc_library(
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/utility",
"@googletest//:gtest",
],
@@ -652,6 +656,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
+ ":config",
":core_headers",
"//absl/synchronization",
"@googletest//:gtest",
@@ -774,6 +779,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":base",
+ ":config",
"//absl/synchronization",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -805,6 +811,7 @@ cc_test(
"no_test_wasm",
],
deps = [
+ ":config",
":malloc_internal",
"//absl/container:node_hash_map",
],
@@ -820,6 +827,7 @@ cc_test(
],
deps = [
":base",
+ ":config",
":core_headers",
"//absl/synchronization",
"@googletest//:gtest",
@@ -882,6 +890,7 @@ cc_test(
"//absl/flags:flag_internal",
"//absl/flags:marshalling",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1030,7 +1039,7 @@ cc_test(
linkstatic = 1,
deps = [
":core_headers",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn
index 3591e5ea904..65447916b37 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn
@@ -96,6 +96,7 @@ absl_source_set("spinlock_wait") {
visibility = [ ":*" ]
deps = [
":base_internal",
+ ":config",
":core_headers",
":errno_saver",
]
@@ -214,6 +215,7 @@ absl_source_set("atomic_hook_test_helper") {
visibility = [ ":*" ]
deps = [
":atomic_hook",
+ ":config",
":core_headers",
]
}
@@ -231,6 +233,7 @@ absl_test("bit_cast_test") {
sources = [ "bit_cast_test.cc" ]
deps = [
":base",
+ ":config",
":core_headers",
]
}
@@ -245,6 +248,7 @@ absl_test("attributes_test") {
if (absl_build_tests) {
import("//testing/test.gni")
+
test("absl_c_header_test") {
sources = [ "c_header_test.c" ]
deps = [
@@ -381,6 +385,7 @@ absl_test("call_once_test") {
sources = [ "call_once_test.cc" ]
deps = [
":base",
+ ":config",
":core_headers",
"//third_party/abseil-cpp/absl/synchronization",
]
@@ -443,6 +448,7 @@ absl_test("sysinfo_test") {
sources = [ "internal/sysinfo_test.cc" ]
deps = [
":base",
+ ":config",
"//third_party/abseil-cpp/absl/synchronization",
]
}
@@ -462,6 +468,7 @@ absl_test("thread_identity_test") {
sources = [ "internal/thread_identity_test.cc" ]
deps = [
":base",
+ ":config",
":core_headers",
"//third_party/abseil-cpp/absl/synchronization",
]
@@ -562,7 +569,6 @@ absl_test("unique_small_name_test") {
sources = [ "internal/unique_small_name_test.cc" ]
deps = [
":core_headers",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt
index 32bcf93951a..77dde8ab274 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt
@@ -365,9 +365,10 @@ absl_cc_library(
${ABSL_TEST_COPTS}
DEPS
absl::config
- absl::pretty_function
absl::memory
absl::meta
+ absl::pretty_function
+ absl::string_view
absl::strings
absl::utility
GTest::gtest
@@ -409,8 +410,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::atomic_hook_test_helper
absl::atomic_hook
+ absl::atomic_hook_test_helper
absl::core_headers
GTest::gmock
GTest::gtest_main
@@ -507,8 +508,8 @@ absl_cc_library(
${ABSL_TEST_COPTS}
DEPS
absl::base
- absl::config
absl::base_internal
+ absl::config
absl::core_headers
absl::synchronization
GTest::gtest
@@ -598,8 +599,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::no_destructor
absl::config
+ absl::no_destructor
absl::raw_logging_internal
GTest::gmock
GTest::gtest_main
@@ -676,10 +677,10 @@ absl_cc_test(
absl_cc_library(
NAME
scoped_set_env
- SRCS
- "internal/scoped_set_env.cc"
HDRS
"internal/scoped_set_env.h"
+ SRCS
+ "internal/scoped_set_env.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -719,6 +720,7 @@ absl_cc_test(
absl::flags_internal
absl::flags_marshalling
absl::log_severity
+ absl::string_view
absl::strings
GTest::gmock
GTest::gtest_main
@@ -728,10 +730,10 @@ absl_cc_test(
absl_cc_library(
NAME
strerror
- SRCS
- "internal/strerror.cc"
HDRS
"internal/strerror.h"
+ SRCS
+ "internal/strerror.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -823,10 +825,10 @@ absl_cc_test(
absl_cc_library(
NAME
poison
- SRCS
- "internal/poison.cc"
HDRS
"internal/poison.h"
+ SRCS
+ "internal/poison.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/attributes.h b/deps/v8/third_party/abseil-cpp/absl/base/attributes.h
index 53e440e68fe..6c788ac1b5d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/attributes.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/attributes.h
@@ -648,7 +648,10 @@
#ifdef ABSL_FALLTHROUGH_INTENDED
#error "ABSL_FALLTHROUGH_INTENDED should not be defined."
#endif
-#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
+#define ABSL_FALLTHROUGH_INTENDED \
+ struct _absl_fallthrough_intended_macro; \
+ (void)sizeof(_absl_fallthrough_intended_macro*); \
+ [[fallthrough]]
// ABSL_DEPRECATED()
//
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/bit_cast_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/bit_cast_test.cc
index 8bded1dcfa6..21a2fdd88b0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/bit_cast_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/bit_cast_test.cc
@@ -20,6 +20,7 @@
#include "gtest/gtest.h"
#include "absl/base/casts.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/call_once.h b/deps/v8/third_party/abseil-cpp/absl/base/call_once.h
index 77852d124fc..58d5d23797a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/call_once.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/call_once.h
@@ -180,8 +180,8 @@ template <typename Callable, typename... Args>
uint32_t old_control = kOnceInit;
if (control->compare_exchange_strong(old_control, kOnceRunning,
std::memory_order_relaxed) ||
- base_internal::SpinLockWait(control, std::size(trans), trans,
- scheduling_mode) == kOnceInit) {
+ base_internal::SpinLockWait(control, static_cast<int>(std::size(trans)),
+ trans, scheduling_mode) == kOnceInit) {
std::invoke(std::forward<Callable>(fn), std::forward<Args>(args)...);
old_control =
control->exchange(base_internal::kOnceDone, std::memory_order_release);
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/call_once_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/call_once_test.cc
index 630e7ce4dfd..16f3c625bcc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/call_once_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/call_once_test.cc
@@ -19,6 +19,7 @@
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/const_init.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/deps/v8/third_party/abseil-cpp/absl/base/dynamic_annotations.h
index 25161ae5019..cac11f31613 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/dynamic_annotations.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/dynamic_annotations.h
@@ -199,6 +199,7 @@
// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
+#pragma GCC visibility push(default)
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateRWLockCreate(const char* file, int line,
const volatile void* lock);
@@ -218,6 +219,7 @@ void AnnotateBenignRaceSized(const char* file, int line,
void AnnotateThreadName(const char* file, int line, const char* name);
void AnnotateEnableRaceDetection(const char* file, int line, int enable);
ABSL_INTERNAL_END_EXTERN_C
+#pragma GCC visibility pop
#else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0
@@ -294,12 +296,14 @@ ABSL_INTERNAL_END_EXTERN_C
// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
+#pragma GCC visibility push(default)
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateIgnoreReadsBegin(const char* file, int line)
ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE;
void AnnotateIgnoreReadsEnd(const char* file,
int line) ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE;
ABSL_INTERNAL_END_EXTERN_C
+#pragma GCC visibility pop
#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED)
@@ -350,10 +354,12 @@ ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL(
// Function prototypes of annotations provided by the compiler-based sanitizer
// implementation.
+#pragma GCC visibility push(default)
ABSL_INTERNAL_BEGIN_EXTERN_C
void AnnotateIgnoreWritesBegin(const char* file, int line);
void AnnotateIgnoreWritesEnd(const char* file, int line);
ABSL_INTERNAL_END_EXTERN_C
+#pragma GCC visibility pop
#else
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc
index 7cf8c36fe35..24b12d45222 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc
@@ -20,7 +20,10 @@
#include <exception>
#include <iostream>
#include <list>
+#include <memory>
+#include <sstream>
#include <type_traits>
+#include <utility>
#include <vector>
#include "gtest/gtest-spi.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.cc
index 537d47cd2d2..5357aadd900 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.cc
@@ -15,6 +15,7 @@
#include "absl/base/internal/atomic_hook_test_helper.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h
index c72015ef966..ce48f30b4a5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h
@@ -15,6 +15,7 @@
#ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_TEST_HELPER_H_
#define ABSL_BASE_INTERNAL_ATOMIC_HOOK_TEST_HELPER_H_
+#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/direct_mmap.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/direct_mmap.h
index f56ba239873..855f51ed96d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/direct_mmap.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/direct_mmap.h
@@ -54,7 +54,9 @@
// SYS_mmap and SYS_munmap are not defined in Android.
#ifdef __BIONIC__
+#pragma GCC visibility push(default)
extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
+#pragma GCC visibility pop
#if defined(__NR_mmap) && !defined(SYS_mmap)
#define SYS_mmap __NR_mmap
#endif
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc
index 6ccac41864b..b358b2d09e4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc
@@ -12,12 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#include "absl/base/internal/exception_safety_testing.h"
#ifdef ABSL_HAVE_EXCEPTIONS
+#include <string>
+
#include "gtest/gtest.h"
#include "absl/meta/type_traits.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
namespace testing {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h
index 7082da78a86..e600b8526b0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h
@@ -25,17 +25,25 @@
#include <cstddef>
#include <cstdint>
+#include <cstdlib>
#include <functional>
#include <initializer_list>
#include <iosfwd>
+#include <limits>
+#include <memory>
+#include <new>
#include <string>
#include <tuple>
+#include <type_traits>
#include <unordered_map>
+#include <utility>
+#include <vector>
#include "gtest/gtest.h"
#include "absl/base/internal/pretty_function.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/utility/utility.h"
@@ -1029,10 +1037,10 @@ class ExceptionSafetyTestBuilder {
ExceptionSafetyTestBuilder<Factory, Operation, Contracts...,
std::decay_t<MoreContracts>...>
WithContracts(const MoreContracts&... more_contracts) const {
- return {
- factory_, operation_,
- std::tuple_cat(contracts_, std::tuple<std::decay_t<MoreContracts>...>(
- more_contracts...))};
+ return {factory_, operation_,
+ std::tuple_cat(
+ contracts_,
+ std::tuple<std::decay_t<MoreContracts>...>(more_contracts...))};
}
/*
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.h
index 26957a3ada0..b86f8847828 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.h
@@ -23,6 +23,7 @@
#ifndef ABSL_BASE_INTERNAL_HARDENING_H_
#define ABSL_BASE_INTERNAL_HARDENING_H_
+#include <atomic>
#include <cstddef>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc
index 3282076f492..2f3a3fd860c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc
@@ -19,9 +19,8 @@
#include <stdlib.h>
#include <thread> // NOLINT(build/c++11)
-#include <unordered_map>
-#include <utility>
+#include "absl/base/config.h"
#include "absl/container/node_hash_map.h"
#ifdef __EMSCRIPTEN__
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h
index 04e44e94fa2..ed832bae399 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h
@@ -21,6 +21,7 @@
#include <atomic>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/thread_identity.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env.cc
index b13e7a2410b..ee5e4f9d95b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env.cc
@@ -16,6 +16,7 @@
#include <cstdlib>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#ifdef _WIN32
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc
index fa824be1c00..ca5492bedf4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc
@@ -16,10 +16,12 @@
// AbslInternalSpinLockDelay() and AbslInternalSpinLockWake().
// See spinlock_wait.h for the specs.
+#include "absl/base/internal/spinlock_wait.h"
+
#include <atomic>
#include <cstdint>
-#include "absl/base/internal/spinlock_wait.h"
+#include "absl/base/config.h"
#if defined(_WIN32)
#include "absl/base/internal/spinlock_win32.inc"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h
index 9a1adcda5ea..2c607eb7b06 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h
@@ -19,8 +19,10 @@
// waiting for those transitions to become possible.
#include <stdint.h>
+
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/internal/scheduling_mode.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/strerror.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/strerror.cc
index e9c4c23b8fa..91594405ad5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/strerror.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/strerror.cc
@@ -22,6 +22,7 @@
#include <string>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/base/internal/errno_saver.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc
index 7248fde9add..985cd2b371e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc
@@ -19,6 +19,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/synchronization/barrier.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.cc
index 27b5816394a..a9d38d30cf1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.cc
@@ -20,10 +20,11 @@
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
-#if !defined(_WIN32) || defined(__MINGW32__)
+#if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11
#include <pthread.h>
#ifndef __wasi__
// WASI does not provide this header, either way we disable use
@@ -86,7 +87,7 @@ void SetCurrentThreadIdentity(ThreadIdentity* identity,
#if defined(__wasi__) || defined(__EMSCRIPTEN__) || defined(__MINGW32__) || \
defined(__hexagon__)
- // Emscripten, WASI and MinGW pthread implementations does not support
+ // Emscripten, WASI and MinGW pthread implementations do not support
// signals. See
// https://kripken.github.io/emscripten-site/docs/porting/pthreads.html for
// more information.
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc
index 94beaa836bf..428de020bba 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc
@@ -20,6 +20,7 @@
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/macros.h"
#include "absl/base/thread_annotations.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
index 9e931808412..02ae823c4c1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
@@ -14,6 +14,7 @@
#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/config.h"
#include "absl/base/internal/unscaledcycleclock_config.h"
#if ABSL_USE_UNSCALED_CYCLECLOCK
@@ -99,9 +100,12 @@ double UnscaledCycleClock::Frequency() {
static once_flag init_timebase_frequency_once;
static double timebase_frequency = 0.0;
base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() {
- size_t length = sizeof(timebase_frequency);
- sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency,
- &length, nullptr, 0);
+ uint64_t freq = 0;
+ size_t length = sizeof(freq);
+ if (sysctlbyname("kern.timecounter.tc.timebase.frequency", &freq, &length,
+ nullptr, 0) == 0) {
+ timebase_frequency = static_cast<double>(freq);
+ }
});
return timebase_frequency;
#else
diff --git a/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.bazel
index dad0d6b85a6..da9a9beb80d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.bazel
@@ -39,6 +39,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:public"], # Should be private, but cleanup is required.
deps = [
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:hardening",
"//absl/utility",
@@ -70,6 +71,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
deps = [
":cleanup",
+ ":cleanup_internal",
"//absl/base:config",
"//absl/utility",
"@googletest//:gtest",
diff --git a/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn
index cf58b066e9a..b7054a52d06 100644
--- a/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn
@@ -9,6 +9,7 @@ import("//third_party/abseil-cpp/absl.gni")
absl_source_set("cleanup_internal") {
public = [ "internal/cleanup.h" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/utility",
@@ -30,6 +31,7 @@ absl_test("cleanup_test") {
sources = [ "cleanup_test.cc" ]
deps = [
":cleanup",
+ ":cleanup_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/utility",
]
diff --git a/deps/v8/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc b/deps/v8/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc
index a413b7efeb2..500dc7a7593 100644
--- a/deps/v8/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/cleanup/cleanup_test.cc
@@ -20,6 +20,7 @@
#include "gtest/gtest.h"
#include "absl/base/config.h"
+#include "absl/cleanup/internal/cleanup.h"
#include "absl/utility/utility.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h b/deps/v8/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h
index f078323d99d..3dfb3458290 100644
--- a/deps/v8/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h
+++ b/deps/v8/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h
@@ -19,6 +19,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/base/internal/hardening.h"
#include "absl/base/macros.h"
#include "absl/base/thread_annotations.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel
index f9b0c5cea66..91f79d6650b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel
@@ -42,6 +42,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:public"], # Should be private, but cleanup is required.
deps = [
+ "//absl/base:config",
"//absl/utility",
],
)
@@ -54,6 +55,7 @@ cc_test(
deps = [
":compressed_tuple",
":test_instance_tracker",
+ "//absl/base:config",
"//absl/memory",
"//absl/utility",
"@googletest//:gtest",
@@ -152,6 +154,7 @@ cc_library(
deps = [
":inlined_vector_internal",
"//absl/algorithm",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:hardening",
"//absl/base:iterator_traits_internal",
@@ -169,6 +172,9 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
textual_hdrs = ["internal/test_allocator.h"],
visibility = ["//visibility:private"],
+ deps = [
+ "//absl/base:config",
+ ],
)
cc_test(
@@ -233,7 +239,10 @@ cc_library(
"//absl:__subpackages__",
"@do_not_use_for_gloop_visibility_only//gloop/util/gtl:__subpackages__",
],
- deps = ["//absl/types:compare"],
+ deps = [
+ "//absl/base:config",
+ "//absl/types:compare",
+ ],
)
cc_test(
@@ -266,6 +275,7 @@ cc_library(
":hash_container_defaults",
":raw_hash_map",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
],
@@ -305,6 +315,7 @@ cc_library(
":hash_container_defaults",
":raw_hash_set",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
"//absl/meta:type_traits",
@@ -322,6 +333,7 @@ cc_test(
":flat_hash_set",
":hash_container_defaults",
":hash_generator_testing",
+ ":hash_policy_testing",
":test_allocator",
":unordered_set_constructor_test",
":unordered_set_lookup_test",
@@ -331,7 +343,7 @@ cc_test(
"//absl/hash",
"//absl/log:check",
"//absl/memory",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -349,6 +361,7 @@ cc_library(
":node_slot_policy",
":raw_hash_map",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
"//absl/meta:type_traits",
@@ -387,6 +400,7 @@ cc_library(
":node_slot_policy",
":raw_hash_set",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
"//absl/meta:type_traits",
@@ -445,7 +459,7 @@ cc_test(
"//absl/base:config",
"//absl/base:no_destructor",
"//absl/meta:type_traits",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -464,8 +478,8 @@ cc_library(
"//absl/base:config",
"//absl/hash",
"//absl/meta:type_traits",
- "//absl/strings",
"//absl/strings:cord",
+ "//absl/strings:string_view",
],
)
@@ -491,11 +505,13 @@ cc_test(
":flat_hash_map",
":flat_hash_set",
":hash_function_defaults",
+ "//absl/base:config",
+ "//absl/base:core_headers",
"//absl/hash",
"//absl/random",
- "//absl/strings",
"//absl/strings:cord",
"//absl/strings:cord_test_helpers",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -515,7 +531,7 @@ cc_library(
"//absl/memory",
"//absl/meta:type_traits",
"//absl/random",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -529,8 +545,9 @@ cc_library(
"@do_not_use_for_gloop_visibility_only//gloop/util/gtl:__subpackages__",
],
deps = [
+ "//absl/base:config",
"//absl/hash",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -541,6 +558,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":hash_policy_testing",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -554,6 +572,7 @@ cc_library(
deps = [
":common_policy_traits",
":container_memory",
+ "//absl/base:config",
"//absl/meta:type_traits",
],
)
@@ -566,6 +585,7 @@ cc_test(
deps = [
":container_memory",
":hash_policy_traits",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -577,7 +597,10 @@ cc_library(
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:private"],
- deps = ["//absl/meta:type_traits"],
+ deps = [
+ "//absl/base:config",
+ "//absl/meta:type_traits",
+ ],
)
cc_test(
@@ -600,6 +623,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":hashtable_debug_hooks",
+ "//absl/base:config",
],
)
@@ -721,6 +745,7 @@ cc_library(
"@do_not_use_for_gloop_visibility_only//gloop/util/gtl:__pkg__",
],
deps = [
+ "//absl/base:config",
"//absl/meta:type_traits",
"//absl/types:optional",
],
@@ -852,6 +877,7 @@ cc_test(
"//absl/numeric:int128",
"//absl/random",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -868,10 +894,14 @@ cc_binary(
deps = [
":container_memory",
":hash_function_defaults",
+ ":hashtable_control_bytes",
":raw_hash_set",
+ "//absl/base:config",
"//absl/base:raw_logging_internal",
+ "//absl/hash",
"//absl/random",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"@google_benchmark//:benchmark_main",
],
)
@@ -896,6 +926,7 @@ cc_binary(
"//absl/random:distributions",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
],
)
@@ -961,6 +992,7 @@ cc_binary(
visibility = ["//visibility:private"],
deps = [
":layout",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"@google_benchmark//:benchmark_main",
@@ -1009,6 +1041,7 @@ cc_library(
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//absl/base:config",
"@googletest//:gtest",
],
)
@@ -1026,6 +1059,7 @@ cc_library(
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//absl/base:config",
"@googletest//:gtest",
],
)
@@ -1059,6 +1093,7 @@ cc_library(
"//absl/container:__pkg__",
],
deps = [
+ "//absl/base:config",
"//absl/meta:type_traits",
"@googletest//:gtest",
],
@@ -1074,6 +1109,7 @@ cc_library(
"//absl/container:__pkg__",
],
deps = [
+ "//absl/base:config",
"//absl/meta:type_traits",
"@googletest//:gtest",
],
@@ -1092,6 +1128,7 @@ cc_library(
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//absl/base:config",
"@googletest//:gtest",
],
)
@@ -1109,6 +1146,7 @@ cc_library(
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//absl/base:config",
"@googletest//:gtest",
],
)
@@ -1120,10 +1158,12 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["no_test_loonix"],
deps = [
+ ":hash_policy_testing",
":unordered_set_constructor_test",
":unordered_set_lookup_test",
":unordered_set_members_test",
":unordered_set_modifiers_test",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1136,10 +1176,12 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["no_test_loonix"],
deps = [
+ ":hash_policy_testing",
":unordered_map_constructor_test",
":unordered_map_lookup_test",
":unordered_map_members_test",
":unordered_map_modifiers_test",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1158,6 +1200,7 @@ cc_test(
":hashtablez_sampler",
":node_hash_map",
":node_hash_set",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1190,8 +1233,8 @@ cc_library(
"//absl/hash:weakly_mixed_integer",
"//absl/memory",
"//absl/meta:type_traits",
- "//absl/strings",
"//absl/strings:cord",
+ "//absl/strings:string_view",
"//absl/types:compare",
],
)
@@ -1206,7 +1249,7 @@ cc_library(
deps = [
":btree",
":flat_hash_set",
- "//absl/strings",
+ "//absl/base:config",
"//absl/strings:cord",
"//absl/time",
],
@@ -1233,6 +1276,7 @@ cc_test(
":test_allocator",
":test_instance_tracker",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/flags:flag",
@@ -1240,6 +1284,8 @@ cc_test(
"//absl/memory",
"//absl/random",
"//absl/strings",
+ "//absl/strings:cord",
+ "//absl/strings:string_view",
"//absl/types:compare",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1263,6 +1309,7 @@ cc_binary(
":flat_hash_set",
":hashtable_debug",
"//absl/algorithm:container",
+ "//absl/base:config",
"//absl/base:raw_logging_internal",
"//absl/hash",
"//absl/log",
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn
index 1c4de821920..f54c4d95d09 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn
@@ -8,7 +8,10 @@ import("//third_party/abseil-cpp/absl.gni")
absl_source_set("compressed_tuple") {
public = [ "internal/compressed_tuple.h" ]
- deps = [ "//third_party/abseil-cpp/absl/utility" ]
+ deps = [
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/utility",
+ ]
}
absl_test("compressed_tuple_test") {
@@ -16,6 +19,7 @@ absl_test("compressed_tuple_test") {
deps = [
":compressed_tuple",
":test_instance_tracker",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/utility",
]
@@ -73,6 +77,7 @@ absl_source_set("inlined_vector") {
deps = [
":inlined_vector_internal",
"//third_party/abseil-cpp/absl/algorithm",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:iterator_traits_internal",
@@ -87,10 +92,8 @@ absl_source_set("test_allocator") {
testonly = true
public = [ "internal/test_allocator.h" ]
visibility = [ ":*" ]
- deps = [
- "//third_party/abseil-cpp/absl/base:config",
- "//third_party/googletest:gtest",
- ]
+ deps = [ "//third_party/abseil-cpp/absl/base:config" ]
+ deps += [ "//third_party/googletest:gtest" ]
}
absl_test("inlined_vector_test") {
@@ -118,7 +121,10 @@ absl_source_set("test_instance_tracker") {
sources = [ "internal/test_instance_tracker.cc" ]
public = [ "internal/test_instance_tracker.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
- deps = [ "//third_party/abseil-cpp/absl/types:compare" ]
+ deps = [
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/types:compare",
+ ]
}
absl_test("test_instance_tracker_test") {
@@ -133,6 +139,7 @@ absl_source_set("flat_hash_map") {
":hash_container_defaults",
":raw_hash_map",
"//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
@@ -162,6 +169,7 @@ absl_source_set("flat_hash_set") {
":hash_container_defaults",
":raw_hash_set",
"//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
@@ -175,6 +183,7 @@ absl_test("flat_hash_set_test") {
":flat_hash_set",
":hash_container_defaults",
":hash_generator_testing",
+ ":hash_policy_testing",
":test_allocator",
":unordered_set_constructor_test",
":unordered_set_lookup_test",
@@ -184,7 +193,6 @@ absl_test("flat_hash_set_test") {
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/log:check",
"//third_party/abseil-cpp/absl/memory",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -197,6 +205,7 @@ absl_source_set("node_hash_map") {
":node_slot_policy",
":raw_hash_map",
"//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
@@ -225,6 +234,7 @@ absl_source_set("node_hash_set") {
":node_slot_policy",
":raw_hash_set",
"//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
@@ -269,7 +279,6 @@ absl_source_set("hash_function_defaults") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/meta:type_traits",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:string_view",
]
@@ -289,9 +298,10 @@ absl_test("hash_function_defaults_test") {
":flat_hash_map",
":flat_hash_set",
":hash_function_defaults",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/random",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:cord_test_helpers",
"//third_party/abseil-cpp/absl/strings:string_view",
@@ -310,7 +320,6 @@ absl_source_set("hash_generator_testing") {
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/random",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -320,15 +329,18 @@ absl_source_set("hash_policy_testing") {
public = [ "internal/hash_policy_testing.h" ]
visibility = [ ":*" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/hash",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
absl_test("hash_policy_testing_test") {
sources = [ "internal/hash_policy_testing_test.cc" ]
- deps = [ ":hash_policy_testing" ]
+ deps = [
+ ":hash_policy_testing",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
}
absl_source_set("hash_policy_traits") {
@@ -337,6 +349,7 @@ absl_source_set("hash_policy_traits") {
deps = [
":common_policy_traits",
":container_memory",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
@@ -346,13 +359,17 @@ absl_test("hash_policy_traits_test") {
deps = [
":container_memory",
":hash_policy_traits",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("common_policy_traits") {
public = [ "internal/common_policy_traits.h" ]
visibility = [ ":*" ]
- deps = [ "//third_party/abseil-cpp/absl/meta:type_traits" ]
+ deps = [
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/meta:type_traits",
+ ]
}
absl_test("common_policy_traits_test") {
@@ -366,7 +383,10 @@ absl_test("common_policy_traits_test") {
absl_source_set("hashtable_debug") {
public = [ "internal/hashtable_debug.h" ]
visibility = [ ":*" ]
- deps = [ ":hashtable_debug_hooks" ]
+ deps = [
+ ":hashtable_debug_hooks",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
}
absl_source_set("hashtable_debug_hooks") {
@@ -448,6 +468,7 @@ absl_source_set("common") {
public = [ "internal/common.h" ]
visibility = [ ":*" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -586,6 +607,7 @@ absl_source_set("unordered_map_lookup_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
@@ -598,6 +620,7 @@ absl_source_set("unordered_map_modifiers_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
@@ -622,6 +645,7 @@ absl_source_set("unordered_set_members_test") {
public = [ "internal/unordered_set_members_test.h" ]
visibility = [ ":*" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
@@ -633,6 +657,7 @@ absl_source_set("unordered_map_members_test") {
public = [ "internal/unordered_map_members_test.h" ]
visibility = [ ":*" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
@@ -646,6 +671,7 @@ absl_source_set("unordered_set_lookup_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
@@ -658,6 +684,7 @@ absl_source_set("unordered_set_modifiers_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
@@ -666,20 +693,24 @@ absl_source_set("unordered_set_modifiers_test") {
absl_test("unordered_set_test") {
sources = [ "internal/unordered_set_test.cc" ]
deps = [
+ ":hash_policy_testing",
":unordered_set_constructor_test",
":unordered_set_lookup_test",
":unordered_set_members_test",
":unordered_set_modifiers_test",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
absl_test("unordered_map_test") {
sources = [ "internal/unordered_map_test.cc" ]
deps = [
+ ":hash_policy_testing",
":unordered_map_constructor_test",
":unordered_map_lookup_test",
":unordered_map_members_test",
":unordered_map_modifiers_test",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
@@ -691,6 +722,7 @@ absl_test("sample_element_size_test") {
":hashtablez_sampler",
":node_hash_map",
":node_hash_set",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
@@ -717,11 +749,11 @@ absl_source_set("btree") {
"//third_party/abseil-cpp/absl/hash:weakly_mixed_integer",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:compare",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_source_set("btree_test_common") {
@@ -731,7 +763,7 @@ absl_source_set("btree_test_common") {
deps = [
":btree",
":flat_hash_set",
- "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/time",
]
@@ -820,6 +852,7 @@ absl_source_set("chunked_queue") {
"//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:iterator_traits_internal",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("chunked_queue_test") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt
index effe790f7e3..cf460f03d8c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt
@@ -39,7 +39,7 @@ absl_cc_library(
absl::layout
absl::memory
absl::raw_logging_internal
- absl::strings
+ absl::string_view
absl::throw_delegate
absl::type_traits
absl::weakly_mixed_integer
@@ -59,7 +59,6 @@ absl_cc_library(
absl::btree
absl::cord
absl::flat_hash_set
- absl::strings
absl::time
TESTONLY
)
@@ -83,6 +82,7 @@ absl_cc_test(
absl::hash_testing
absl::random_random
absl::raw_logging_internal
+ absl::string_view
absl::strings
absl::test_allocator
absl::test_instance_tracker
@@ -125,15 +125,15 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::compressed_tuple
absl::algorithm
+ absl::compressed_tuple
absl::config
absl::core_headers
absl::dynamic_annotations
absl::hardening
absl::iterator_traits_internal
- absl::throw_delegate
absl::memory
+ absl::throw_delegate
absl::weakly_mixed_integer
PUBLIC
)
@@ -146,9 +146,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::fixed_array
absl::config
absl::exception_testing
+ absl::fixed_array
absl::hash_testing
absl::iterator_traits_test_helper_internal
absl::memory
@@ -164,9 +164,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::fixed_array
absl::config
absl::exception_safety_testing
+ absl::fixed_array
GTest::gmock_main
)
@@ -202,8 +202,8 @@ absl_cc_library(
absl::core_headers
absl::hardening
absl::inlined_vector_internal
- absl::throw_delegate
absl::memory
+ absl::throw_delegate
absl::type_traits
absl::weakly_mixed_integer
PUBLIC
@@ -252,9 +252,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::inlined_vector
absl::config
absl::exception_safety_testing
+ absl::inlined_vector
GTest::gmock_main
)
@@ -293,11 +293,11 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::algorithm_container
absl::container_memory
absl::core_headers
absl::hash_container_defaults
absl::raw_hash_map
- absl::algorithm_container
absl::type_traits
PUBLIC
)
@@ -332,12 +332,12 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::container_memory
- absl::hash_container_defaults
- absl::raw_hash_set
absl::algorithm_container
+ absl::container_memory
absl::core_headers
+ absl::hash_container_defaults
absl::memory
+ absl::raw_hash_set
absl::type_traits
PUBLIC
)
@@ -358,7 +358,7 @@ absl_cc_test(
absl::hash_container_defaults
absl::hash_generator_testing
absl::memory
- absl::strings
+ absl::string_view
absl::test_allocator
absl::unordered_set_constructor_test
absl::unordered_set_lookup_test
@@ -375,13 +375,13 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::algorithm_container
absl::container_memory
absl::core_headers
absl::hash_container_defaults
+ absl::memory
absl::node_slot_policy
absl::raw_hash_map
- absl::algorithm_container
- absl::memory
absl::type_traits
PUBLIC
)
@@ -413,13 +413,13 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::algorithm_container
absl::container_memory
absl::core_headers
absl::hash_container_defaults
+ absl::memory
absl::node_slot_policy
absl::raw_hash_set
- absl::algorithm_container
- absl::memory
absl::type_traits
PUBLIC
)
@@ -485,7 +485,7 @@ absl_cc_test(
absl::config
absl::container_memory
absl::no_destructor
- absl::strings
+ absl::string_view
absl::test_instance_tracker
absl::type_traits
GTest::gmock_main
@@ -504,7 +504,7 @@ absl_cc_library(
absl::container_common
absl::cord
absl::hash
- absl::strings
+ absl::string_view
absl::type_traits
PUBLIC
)
@@ -521,10 +521,10 @@ absl_cc_test(
absl::cord_test_helpers
absl::flat_hash_map
absl::flat_hash_set
- absl::hash_function_defaults
absl::hash
+ absl::hash_function_defaults
absl::random_random
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -545,7 +545,7 @@ absl_cc_library(
absl::meta
absl::no_destructor
absl::random_random
- absl::strings
+ absl::string_view
TESTONLY
)
@@ -559,7 +559,7 @@ absl_cc_library(
${ABSL_TEST_COPTS}
DEPS
absl::hash
- absl::strings
+ absl::string_view
TESTONLY
)
@@ -584,8 +584,8 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::container_memory
absl::common_policy_traits
+ absl::container_memory
absl::meta
PUBLIC
)
@@ -726,13 +726,13 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::config
absl::common_policy_traits
+ absl::config
absl::container_memory
absl::core_headers
absl::raw_hash_set
- absl::type_traits
absl::throw_delegate
+ absl::type_traits
PUBLIC
)
@@ -843,6 +843,7 @@ absl_cc_test(
absl::prefetch
absl::random_random
absl::raw_hash_set
+ absl::string_view
absl::strings
absl::test_allocator
absl::test_instance_tracker
@@ -904,8 +905,8 @@ absl_cc_library(
absl::core_headers
absl::debugging_internal
absl::meta
- absl::strings
absl::span
+ absl::strings
absl::utility
PUBLIC
)
@@ -918,9 +919,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::layout
absl::check
absl::config
+ absl::layout
absl::span
absl::utility
GTest::gmock_main
@@ -1099,9 +1100,9 @@ absl_cc_test(
DEPS
absl::flat_hash_map
absl::flat_hash_set
+ absl::hashtablez_sampler
absl::node_hash_map
absl::node_hash_set
- absl::hashtablez_sampler
GTest::gmock_main
)
@@ -1131,8 +1132,8 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::container_common
absl::config
+ absl::container_common
absl::core_headers
absl::flat_hash_set
)
@@ -1147,11 +1148,11 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::linked_hash_set
absl::config
- absl::heterogeneous_lookup_testing
absl::hash_generator_testing
absl::hash_policy_testing
+ absl::heterogeneous_lookup_testing
+ absl::linked_hash_set
absl::string_view
absl::test_allocator
absl::test_instance_tracker
@@ -1172,8 +1173,8 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::container_common
absl::config
+ absl::container_common
absl::core_headers
absl::flat_hash_set
absl::throw_delegate
@@ -1189,12 +1190,12 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::linked_hash_map
absl::config
absl::exception_testing
- absl::heterogeneous_lookup_testing
absl::hash_generator_testing
absl::hash_policy_testing
+ absl::heterogeneous_lookup_testing
+ absl::linked_hash_map
absl::string_view
absl::test_allocator
absl::test_instance_tracker
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/btree_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/container/btree_benchmark.cc
index 69a81959285..9ccee4d3bb7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/btree_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/btree_benchmark.cc
@@ -15,8 +15,11 @@
#include <stdint.h>
#include <algorithm>
+#include <array>
+#include <cstddef>
#include <functional>
#include <map>
+#include <memory>
#include <numeric>
#include <random>
#include <set>
@@ -24,9 +27,11 @@
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
+#include <utility>
#include <vector>
#include "absl/algorithm/container.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/btree_map.h b/deps/v8/third_party/abseil-cpp/absl/container/btree_map.h
index 257a6246de8..0aaf2e7c6cb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/btree_map.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/btree_map.h
@@ -63,6 +63,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/container/internal/btree.h" // IWYU pragma: export
#include "absl/container/internal/btree_container.h" // IWYU pragma: export
#include "absl/container/internal/common.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/btree_set.h b/deps/v8/third_party/abseil-cpp/absl/container/btree_set.h
index 368c6a7b9e6..892dc886a68 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/btree_set.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/btree_set.h
@@ -62,6 +62,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/container/internal/btree.h" // IWYU pragma: export
#include "absl/container/internal/btree_container.h" // IWYU pragma: export
#include "absl/container/internal/common.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/btree_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/btree_test.cc
index 5b76c34a0f4..a2c8648502f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/btree_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/btree_test.cc
@@ -16,6 +16,7 @@
#include <algorithm>
#include <array>
+#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
@@ -25,6 +26,7 @@
#include <memory>
#include <numeric>
#include <optional>
+#include <set>
#include <stdexcept>
#include <string>
#include <type_traits>
@@ -34,6 +36,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/algorithm/container.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/container/btree_map.h"
@@ -44,6 +47,7 @@
#include "absl/hash/hash_testing.h"
#include "absl/memory/memory.h"
#include "absl/random/random.h"
+#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/btree_test.h b/deps/v8/third_party/abseil-cpp/absl/container/btree_test.h
index 79c3d95bf07..da1618ee614 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/btree_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/btree_test.h
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_set.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/fixed_array_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/fixed_array_test.cc
index 71c6819bbdf..e82919e5a07 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/fixed_array_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/fixed_array_test.cc
@@ -16,6 +16,8 @@
#include <stdio.h>
+#include <cassert>
+#include <cstdint>
#include <cstring>
#include <forward_list>
#include <iterator>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map.h b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map.h
index e11d7e2e796..82334094aa4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map.h
@@ -39,6 +39,7 @@
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set.h b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set.h
index ed977431cc6..b0527b33301 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set.h
@@ -39,6 +39,7 @@
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
@@ -588,9 +589,9 @@ struct FlatHashSetPolicy {
static size_t space_used(const T*) { return 0; }
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedApplyToSlotFn<Hash, T, kIsDefault, kSeedShift>;
+ return &TypeErasedApplyToSlotFn<Hash, T, kIsAbsl, kSeedShift>;
}
};
} // namespace container_internal
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
index 95ead482a8f..6c99e8d510a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc
@@ -28,6 +28,7 @@
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_generator_testing.h"
+#include "absl/container/internal/hash_policy_testing.h"
#include "absl/container/internal/test_allocator.h"
#include "absl/container/internal/unordered_set_constructor_test.h"
#include "absl/container/internal/unordered_set_lookup_test.h"
@@ -388,14 +389,14 @@ TEST(FlatHashSet, MoveOnlyKey) {
TEST(FlatHashSet, IsDefaultHash) {
using absl::container_internal::hashtable_debug_internal::
HashtableDebugAccess;
- EXPECT_EQ(HashtableDebugAccess<flat_hash_set<int>>::kIsDefaultHash, true);
- EXPECT_EQ(HashtableDebugAccess<flat_hash_set<std::string>>::kIsDefaultHash,
+ EXPECT_EQ(HashtableDebugAccess<flat_hash_set<int>>::kIsAbslHash, true);
+ EXPECT_EQ(HashtableDebugAccess<flat_hash_set<std::string>>::kIsAbslHash,
true);
struct Hash {
size_t operator()(size_t i) const { return i; }
};
- EXPECT_EQ((HashtableDebugAccess<flat_hash_set<size_t, Hash>>::kIsDefaultHash),
+ EXPECT_EQ((HashtableDebugAccess<flat_hash_set<size_t, Hash>>::kIsAbslHash),
false);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector.h b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector.h
index 8dfbf03c64c..f777f1f7965 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector.h
@@ -41,12 +41,14 @@
#include <cstring>
#include <initializer_list>
#include <iterator>
+#include <limits>
#include <memory>
#include <type_traits>
#include <utility>
#include "absl/algorithm/algorithm.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/hardening.h"
#include "absl/base/internal/iterator_traits.h"
#include "absl/base/macros.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
index 5a04277c6fb..e3f81bbed14 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc
@@ -13,9 +13,13 @@
// limitations under the License.
#include <array>
+#include <cstddef>
+#include <cstdint>
#include <string>
+#include <utility>
#include <vector>
+#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/container/inlined_vector.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
index 73584edde34..8bed8479add 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/inlined_vector_test.cc
@@ -16,6 +16,7 @@
#include <algorithm>
#include <cstddef>
+#include <cstdint>
#include <forward_list>
#include <iterator>
#include <list>
@@ -1802,16 +1803,26 @@ TEST(AllocatorSupportTest, Constructors) {
const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
int64_t allocated = 0;
MyAlloc alloc(&allocated);
- { AllocVec ABSL_ATTRIBUTE_UNUSED v; }
- { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); }
{
- AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + std::size(ia), alloc);
+ [[maybe_unused]] AllocVec v;
+ }
+ {
+ [[maybe_unused]] AllocVec v(alloc);
+ }
+ {
+ [[maybe_unused]] AllocVec v(ia, ia + std::size(ia), alloc);
+ }
+ {
+ [[maybe_unused]] AllocVec v({1, 2, 3}, alloc);
}
- { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); }
AllocVec v2;
- { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); }
- { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); }
+ {
+ [[maybe_unused]] AllocVec v(v2, alloc);
+ }
+ {
+ [[maybe_unused]] AllocVec v(std::move(v2), alloc);
+ }
}
TEST(AllocatorSupportTest, CountAllocations) {
@@ -1822,14 +1833,14 @@ TEST(AllocatorSupportTest, CountAllocations) {
int64_t instance_count = 0;
MyAlloc alloc(&bytes_allocated, &instance_count);
{
- AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc);
+ [[maybe_unused]] AllocVec v(ia, ia + 4, alloc);
EXPECT_THAT(bytes_allocated, Eq(0));
EXPECT_THAT(instance_count, Eq(4));
}
EXPECT_THAT(bytes_allocated, Eq(0));
EXPECT_THAT(instance_count, Eq(0));
{
- AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + std::size(ia), alloc);
+ [[maybe_unused]] AllocVec v(ia, ia + std::size(ia), alloc);
EXPECT_THAT(bytes_allocated,
Eq(static_cast<int64_t>(v.size() * sizeof(int))));
EXPECT_THAT(instance_count, Eq(static_cast<int64_t>(v.size())));
@@ -1843,12 +1854,12 @@ TEST(AllocatorSupportTest, CountAllocations) {
int64_t bytes_allocated2 = 0;
MyAlloc alloc2(&bytes_allocated2);
- ABSL_ATTRIBUTE_UNUSED AllocVec v2(v, alloc2);
+ [[maybe_unused]] AllocVec v2(v, alloc2);
EXPECT_THAT(bytes_allocated2, Eq(0));
int64_t bytes_allocated3 = 0;
MyAlloc alloc3(&bytes_allocated3);
- ABSL_ATTRIBUTE_UNUSED AllocVec v3(std::move(v), alloc3);
+ [[maybe_unused]] AllocVec v3(std::move(v), alloc3);
EXPECT_THAT(bytes_allocated3, Eq(0));
}
EXPECT_THAT(bytes_allocated, Eq(0));
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/btree_container.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/btree_container.h
index 8a4582f22aa..eb7dfd1914f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/btree_container.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/btree_container.h
@@ -23,6 +23,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/throw_delegate.h"
#include "absl/container/internal/btree.h" // IWYU pragma: export
#include "absl/container/internal/common.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/common.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/common.h
index b2839e6e24d..c438068a959 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/common.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/common.h
@@ -22,6 +22,7 @@
#include <tuple>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/types/optional.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h
index 0eb05427ca9..2d65fe7a54a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h
@@ -22,6 +22,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h
index 4d0fb2a08e2..fa53636c28a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h
@@ -32,11 +32,13 @@
#ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
#define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
+#include <cstddef>
#include <initializer_list>
#include <tuple>
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/utility/utility.h"
#if defined(_MSC_VER) && !defined(__NVCC__)
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc
index 2331fc4463e..e22fafa2ce1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc
@@ -25,6 +25,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/test_instance_tracker.h"
#include "absl/memory/memory.h"
#include "absl/utility/utility.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory.h
index fceb4ebaae1..b03eb952de2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory.h
@@ -486,13 +486,13 @@ struct map_slot_policy {
// Variadic arguments hash function that ignore the rest of the arguments.
// Useful for usage with policy traits.
-template <class Hash, bool kIsDefault, size_t kSeedShift>
+template <class Hash, bool kIsAbsl, size_t kSeedShift>
struct HashElement {
HashElement(const Hash& h, size_t s) : hash(h), seed(s >> kSeedShift) {}
template <class K, class... Args>
size_t operator()(const K& key, Args&&...) const {
- if constexpr (kIsDefault) {
+ if constexpr (kIsAbsl) {
// TODO(b/384509507): resolve `no header providing
// "absl::hash_internal::SupportsHashWithSeed" is directly included`.
// Maybe we should make "internal/hash.h" be a separate library.
@@ -506,12 +506,12 @@ struct HashElement {
};
// No arguments function hash function for a specific key.
-template <class Hash, class Key, bool kIsDefault, size_t kSeedShift>
+template <class Hash, class Key, bool kIsAbsl, size_t kSeedShift>
struct HashKey {
HashKey(const Hash& h, const Key& k) : hash(h), key(k) {}
size_t operator()(size_t seed) const {
- return HashElement<Hash, kIsDefault, kSeedShift>{hash, seed}(key);
+ return HashElement<Hash, kIsAbsl, kSeedShift>{hash, seed}(key);
}
const Hash& hash;
const Key& key;
@@ -534,31 +534,31 @@ using HashSlotFn = size_t (*)(const void* hash_fn, void* slot, size_t seed);
// Type erased function to apply `Fn` to data inside of the `slot`.
// The data is expected to have type `T`.
-template <class Fn, class T, bool kIsDefault, size_t kSeedShift>
+template <class Fn, class T, bool kIsAbsl, size_t kSeedShift>
size_t TypeErasedApplyToSlotFn(const void* fn, void* slot, size_t seed) {
const auto* f = static_cast<const Fn*>(fn);
- return HashElement<Fn, kIsDefault, kSeedShift>{
+ return HashElement<Fn, kIsAbsl, kSeedShift>{
*f, seed}(*static_cast<const T*>(slot));
}
// Type erased function to apply `Fn` to data inside of the `*slot_ptr`.
// The data is expected to have type `T`.
-template <class Fn, class T, bool kIsDefault, size_t kSeedShift>
+template <class Fn, class T, bool kIsAbsl, size_t kSeedShift>
size_t TypeErasedDerefAndApplyToSlotFn(const void* fn, void* slot_ptr,
size_t seed) {
const auto* f = static_cast<const Fn*>(fn);
const T* slot = *static_cast<T**>(slot_ptr);
- return HashElement<Fn, kIsDefault, kSeedShift>{*f, seed}(*slot);
+ return HashElement<Fn, kIsAbsl, kSeedShift>{*f, seed}(*slot);
}
// Type erased function to apply `Fn` to data inside of the `slot_ptr->first`.
// The data is expected to have type `T`.
-template <class Fn, class T, bool kIsDefault, size_t kSeedShift>
+template <class Fn, class T, bool kIsAbsl, size_t kSeedShift>
size_t TypeErasedDerefAndApplyToSlotFirstFn(const void* fn, void* slot_ptr,
size_t seed) {
const auto* f = static_cast<const Fn*>(fn);
const T* slot = *static_cast<T**>(slot_ptr);
- return HashElement<Fn, kIsDefault, kSeedShift>{*f, seed}(slot->first);
+ return HashElement<Fn, kIsAbsl, kSeedShift>{*f, seed}(slot->first);
}
} // namespace container_internal
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc
index 1aa459c2c8a..70fc0eab636 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc
@@ -16,7 +16,10 @@
#include <cstddef>
#include <cstdint>
+#include <cstring>
+#include <map>
#include <memory>
+#include <string>
#include <tuple>
#include <type_traits>
#include <typeindex>
@@ -313,9 +316,9 @@ TEST(ApplyTest, TypeErasedApplyToSlotFn) {
size_t x = 7;
size_t seed = 100;
auto fn = [](size_t v) { return v * 2; };
- EXPECT_EQ((TypeErasedApplyToSlotFn<decltype(fn), size_t, /*kIsDefault=*/false,
+ EXPECT_EQ((TypeErasedApplyToSlotFn<decltype(fn), size_t, /*kIsAbsl=*/false,
/*kSeedShift=*/0>(&fn, &x, seed)),
- (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
+ (HashElement<decltype(fn), /*kIsAbsl=*/false, /*kSeedShift=*/0>(
fn, seed)(x)));
}
@@ -326,9 +329,9 @@ TEST(ApplyTest, TypeErasedDerefAndApplyToSlotFn) {
size_t* x_ptr = &x;
EXPECT_EQ(
(TypeErasedDerefAndApplyToSlotFn<decltype(fn), size_t,
- /*kIsDefault=*/false,
+ /*kIsAbsl=*/false,
/*kSeedShift=*/0>(&fn, &x_ptr, seed)),
- (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
+ (HashElement<decltype(fn), /*kIsAbsl=*/false, /*kSeedShift=*/0>(
fn, seed)(x)));
}
@@ -341,7 +344,7 @@ TEST(HashElement, DefaultHash) {
return v * 2 + seed * 3;
}
} hash;
- EXPECT_EQ((HashElement<HashWithSeed, /*kIsDefault=*/true,
+ EXPECT_EQ((HashElement<HashWithSeed, /*kIsAbsl=*/true,
/*kSeedShift=*/0>(hash, seed)(x)),
hash.hash_with_seed(x, seed));
}
@@ -351,7 +354,7 @@ TEST(HashElement, NonDefaultHash) {
size_t seed = 100;
auto fn = [](size_t v) { return v * 2; };
EXPECT_EQ(
- (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
+ (HashElement<decltype(fn), /*kIsAbsl=*/false, /*kSeedShift=*/0>(
fn, seed)(x)),
fn(x) ^ seed);
}
@@ -361,7 +364,7 @@ TEST(HashElement, NonDefaultHashWithSeedShift) {
size_t seed = 100;
auto fn = [](size_t v) { return v * 2; };
EXPECT_EQ(
- (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/1>(
+ (HashElement<decltype(fn), /*kIsAbsl=*/false, /*kSeedShift=*/1>(
fn, seed)(x)),
fn(x) ^ (seed >> 1));
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc
index 67c853cfdf4..64a5a04bc2d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc
@@ -14,14 +14,20 @@
#include "absl/container/internal/hash_function_defaults.h"
+#include <algorithm>
#include <cstddef>
+#include <cstdint>
#include <functional>
+#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
+#include <vector>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/base/port.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/hash/hash.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc
index 4ae58da1feb..6dbd3f1854f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc
@@ -19,6 +19,7 @@
#include <random>
#include <string>
+#include "absl/base/config.h"
#include "absl/base/no_destructor.h"
#include "absl/random/random.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h
index 79bff7c1001..72ef356a88d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h
@@ -22,6 +22,7 @@
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <iosfwd>
#include <memory>
#include <random>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h
index 5eea528f313..09617b3244b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h
@@ -22,10 +22,12 @@
#include <limits>
#include <memory>
#include <ostream>
+#include <string>
#include <type_traits>
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/hash/hash.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc
index f0b20fe345e..1f0362cb24c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc
@@ -14,7 +14,10 @@
#include "absl/container/internal/hash_policy_testing.h"
+#include <utility>
+
#include "gtest/gtest.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
index beed150b1d1..acea6b7454b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
@@ -21,6 +21,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/container/internal/common_policy_traits.h"
#include "absl/container/internal/container_memory.h"
#include "absl/meta/type_traits.h"
@@ -146,7 +147,7 @@ template <class Policy, class = void>
return P::value(elem);
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
// get_hash_slot_fn may return nullptr to signal that non type erased function
// should be used. GCC warns against comparing function address with nullptr.
@@ -155,10 +156,10 @@ template <class Policy, class = void>
// silent error: the address of * will never be NULL [-Werror=address]
#pragma GCC diagnostic ignored "-Waddress"
#endif
- return Policy::template get_hash_slot_fn<Hash, kIsDefault, kSeedShift>() ==
+ return Policy::template get_hash_slot_fn<Hash, kIsAbsl, kSeedShift>() ==
nullptr
- ? &hash_slot_fn_non_type_erased<Hash, kIsDefault, kSeedShift>
- : Policy::template get_hash_slot_fn<Hash, kIsDefault,
+ ? &hash_slot_fn_non_type_erased<Hash, kIsAbsl, kSeedShift>
+ : Policy::template get_hash_slot_fn<Hash, kIsAbsl,
kSeedShift>();
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
@@ -169,11 +170,11 @@ template <class Policy, class = void>
static constexpr bool soo_enabled() { return soo_enabled_impl(Rank1{}); }
private:
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static size_t hash_slot_fn_non_type_erased(const void* hash_fn, void* slot,
size_t seed) {
return Policy::apply(
- HashElement<Hash, kIsDefault, kSeedShift>{
+ HashElement<Hash, kIsAbsl, kSeedShift>{
*static_cast<const Hash*>(hash_fn), seed},
Policy::element(static_cast<slot_type*>(slot)));
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc
index 8d498e0ff0f..ebe8074f335 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc
@@ -21,6 +21,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/container_memory.h"
namespace absl {
@@ -45,7 +46,7 @@ struct PolicyWithoutOptionalOps {
static std::function<int(int)> apply_impl;
static std::function<Slot&(Slot*)> value;
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -99,7 +100,7 @@ struct PolicyNoHashFn {
return fn(v);
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -108,9 +109,9 @@ struct PolicyNoHashFn {
size_t* PolicyNoHashFn::apply_called_count;
struct PolicyCustomHashFn : PolicyNoHashFn {
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedApplyToSlotFn<Hash, int, kIsDefault, kSeedShift>;
+ return &TypeErasedApplyToSlotFn<Hash, int, kIsAbsl, kSeedShift>;
}
};
@@ -121,10 +122,10 @@ TEST(HashTest, PolicyNoHashFn_get_hash_slot_fn) {
Hash hasher;
Slot value = 7;
auto* fn = hash_policy_traits<PolicyNoHashFn>::get_hash_slot_fn<
- Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>();
+ Hash, /*kIsAbsl=*/false, /*kSeedShift=*/6>();
EXPECT_NE(fn, nullptr);
EXPECT_EQ(fn(&hasher, &value, 100),
- (HashElement<Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>(
+ (HashElement<Hash, /*kIsAbsl=*/false, /*kSeedShift=*/6>(
hasher, 100)(value)));
EXPECT_EQ(apply_called_count, 1);
}
@@ -136,12 +137,12 @@ TEST(HashTest, PolicyCustomHashFn_get_hash_slot_fn) {
Hash hasher;
Slot value = 7;
auto* fn = hash_policy_traits<PolicyCustomHashFn>::get_hash_slot_fn<
- Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>();
+ Hash, /*kIsAbsl=*/false, /*kSeedShift=*/6>();
EXPECT_EQ(fn,
- (PolicyCustomHashFn::get_hash_slot_fn<Hash, /*kIsDefault=*/false,
+ (PolicyCustomHashFn::get_hash_slot_fn<Hash, /*kIsAbsl=*/false,
/*kSeedShift=*/6>()));
EXPECT_EQ(fn(&hasher, &value, 100),
- (HashElement<Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>(
+ (HashElement<Hash, /*kIsAbsl=*/false, /*kSeedShift=*/6>(
hasher, 100)(value)));
EXPECT_EQ(apply_called_count, 0);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h
index c79c1a98912..1b2bc951290 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h
@@ -30,11 +30,12 @@
#ifndef ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_
#define ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_
-#include <cstddef>
#include <algorithm>
+#include <cstddef>
#include <type_traits>
#include <vector>
+#include "absl/base/config.h"
#include "absl/container/internal/hashtable_debug_hooks.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
index eff44bf674d..9e9a47c0af3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
@@ -44,6 +44,7 @@
#include <cstdint>
#include <functional>
#include <memory>
+#include <utility>
#include <vector>
#include "absl/base/attributes.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc
index ed35a7eec3d..01cd3b17d5f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/container/internal/hashtablez_sampler.h"
-
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/container/internal/hashtablez_sampler.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
index ae89c023244..0d863a8d965 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
@@ -14,6 +14,7 @@
#include "absl/container/internal/hashtablez_sampler.h"
+#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstddef>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/inlined_vector.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/inlined_vector.h
index 5b9763e9738..e9eafdd1992 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/inlined_vector.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/inlined_vector.h
@@ -29,6 +29,7 @@
#include "absl/base/config.h"
#include "absl/base/internal/hardening.h"
#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
index d6f2669760b..b427f95732e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
@@ -18,6 +18,7 @@
#include <cstddef>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/container/internal/layout.h"
#include "benchmark/benchmark.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc
index 3f9263c4d3d..fb684681a16 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc
@@ -22,6 +22,7 @@
#include <cstring>
#include <memory>
#include <tuple>
+#include <type_traits>
#include <utility>
#include "absl/base/attributes.h"
@@ -262,7 +263,7 @@ void IterateOverFullSlotsImpl(const CommonFields& c, size_t slot_size, Fn cb) {
return;
}
size_t remaining = c.size();
- ABSL_ATTRIBUTE_UNUSED const size_t original_size_for_assert = remaining;
+ [[maybe_unused]] const size_t original_size_for_assert = remaining;
while (remaining != 0) {
for (uint32_t i : GroupFullEmptyOrDeleted(ctrl).MaskFull()) {
ABSL_SWISSTABLE_ASSERT(IsFull(ctrl[i]) &&
@@ -282,58 +283,6 @@ void IterateOverFullSlotsImpl(const CommonFields& c, size_t slot_size, Fn cb) {
"hash table was modified unexpectedly");
}
-// NOTE: we don't use structure with bit fields for GrowthInfo because for
-// correctness we rely on the lower bound being the most significant byte.
-
-// Returns the increment that needs to be added to the packed full growth info
-// in order to increase lower bound by lower_bound_increment and increase
-// overflow growth left by overflow_increment.
-constexpr uint64_t GetPackedIncrement(uint64_t lower_bound_increment,
- uint64_t overflow_increment) {
- return (lower_bound_increment << GrowthInfoAccessor::kLowerBoundShift) +
- overflow_increment;
-}
-
-// Returns the increment that needs to be added to the packed full growth info
-// in order to increase lower bound by overflow_to_lower_bound_size and
-// decrease overflow growth left by overflow_to_lower_bound_size.
-constexpr uint64_t GetRebalanceIncrement(
- uint64_t overflow_to_lower_bound_size) {
- return GetPackedIncrement(overflow_to_lower_bound_size,
- 0u - overflow_to_lower_bound_size);
-}
-
-// Returns the number of elements left to grow in the full growth info.
-constexpr uint64_t GetOverflowGrowthLeftFromPacked(
- uint64_t packed_full_growth_info) {
- constexpr uint64_t kFullGrowthMask =
- (uint64_t{1} << GrowthInfoAccessor::kLowerBoundShift) - 1;
- return packed_full_growth_info & kFullGrowthMask;
-}
-
-// Returns the GrowthInfoLowerBound object containing the information
-// about minimum growth left.
-constexpr GrowthInfoLowerBound GetGrowthInfoLowerBoundFromPacked(
- uint64_t packed_full_growth_info) {
- return GrowthInfoLowerBound(packed_full_growth_info >>
- GrowthInfoAccessor::kLowerBoundShift);
-}
-
-// Returns the number of elements left to grow in the lower bound.
-constexpr uint64_t GetGrowthLeftLowerBoundFromPacked(
- uint64_t packed_full_growth_info) {
- return GetGrowthInfoLowerBoundFromPacked(packed_full_growth_info)
- .GetGrowthLeft();
-}
-
-// Returns the total number of elements left to grow in the full growth info.
-// Assumes that the table has capacity > kMaxGrowthLeftLowerBound.
-uint64_t GetGrowthLeftTotalBigCapacity(void* full_growth_info) {
- uint64_t packed_full_growth_left = little_endian::Load64(full_growth_info);
- return GetOverflowGrowthLeftFromPacked(packed_full_growth_left) +
- GetGrowthLeftLowerBoundFromPacked(packed_full_growth_left);
-}
-
} // namespace
void CommonFields::AssertNotDebugCapacityImpl() const {
@@ -357,21 +306,55 @@ void CommonFields::AssertNotDebugCapacityImpl() const {
}
}
-void GrowthInfoAccessor::InitGrowthLeftNoDeleted(size_t growth_left,
- size_t capacity) {
+void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) {
+ ABSL_SWISSTABLE_ASSERT(ctrl[capacity] == ctrl_t::kSentinel);
+ ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
+ for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) {
+ Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos);
+ }
+ // Copy the cloned ctrl bytes.
+ std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes());
+ ctrl[capacity] = ctrl_t::kSentinel;
+}
+
+void IterateOverFullSlots(const CommonFields& c, size_t slot_size,
+ absl::FunctionRef<void(const ctrl_t*, void*)> cb) {
+ IterateOverFullSlotsImpl(c, slot_size, cb);
+}
+
+void CommonFields::InitGrowthLeftNoDeleted(size_t growth_left,
+ size_t capacity) {
if (capacity <= GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
- *growth_info_lower_bound_ = static_cast<uint8_t>(growth_left);
+ inline_data_.set_growth_info_lower_bound(
+ GrowthInfoLowerBound(static_cast<uint8_t>(growth_left)));
} else {
- uint64_t lower_bound =
- (std::min)(uint64_t{growth_left},
- GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
- little_endian::Store64(
- full_growth_info_ptr(),
- GetPackedIncrement(lower_bound, growth_left - lower_bound));
+ size_t lower_bound = (std::min)(
+ growth_left,
+ GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
+ inline_data_.set_growth_info_lower_bound(
+ GrowthInfoLowerBound(static_cast<uint8_t>(lower_bound)));
+ SetGrowthInfoOverflow(growth_left - lower_bound);
}
}
-GrowthInfoLowerBound GrowthInfoAccessor::RebalanceGrowthLeftLowerBound(
+size_t CommonFields::GetGrowthLeftTotalSlow(size_t capacity) const {
+ size_t result = inline_data_.growth_info_lower_bound().GetGrowthLeft();
+ if (capacity > GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
+ result += GetOverflowGrowthLeft();
+ }
+ return result;
+}
+
+void CommonFields::OverwriteFullAsEmpty() {
+ if (inline_data_.growth_info_lower_bound().GetGrowthLeft() <
+ GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
+ inline_data_.overwrite_full_as_empty_in_lower_bound();
+ } else {
+ SetGrowthInfoOverflow(GetOverflowGrowthLeft() + 1);
+ }
+}
+
+GrowthInfoLowerBound CommonFields::RebalanceGrowthLeftLowerBound(
size_t capacity) {
auto growth_left_lower_bound = GetGrowthInfoLowerBound();
if (capacity <= GrowthInfoLowerBound::kMaxGrowthLeftLowerBound ||
@@ -384,69 +367,26 @@ GrowthInfoLowerBound GrowthInfoAccessor::RebalanceGrowthLeftLowerBound(
}
}
-size_t GrowthInfoAccessor::GetGrowthLeftTotalSlow(size_t capacity) const {
- if (capacity <= GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
- return GetGrowthLeftLowerBound();
- } else {
- return static_cast<size_t>(
- GetGrowthLeftTotalBigCapacity(full_growth_info_ptr()));
- }
-}
-
ABSL_ATTRIBUTE_NOINLINE GrowthInfoLowerBound
-GrowthInfoAccessor::RebalanceGrowthLeftLowerBoundLargeCapacity() {
- void* full_growth_info = full_growth_info_ptr();
- uint64_t packed_full_growth_info = little_endian::Load64(full_growth_info);
- uint64_t overflow_growth_left =
- GetOverflowGrowthLeftFromPacked(packed_full_growth_info);
- uint64_t lower_bound_growth_left =
- GetGrowthLeftLowerBoundFromPacked(packed_full_growth_info);
- uint64_t overflow_to_lower_bound_size =
+CommonFields::RebalanceGrowthLeftLowerBoundLargeCapacity() {
+ size_t overflow_growth_left = GetOverflowGrowthLeft();
+ size_t lower_bound_growth_left = GetGrowthLeftLowerBound();
+ size_t overflow_to_lower_bound_size =
(std::min)(overflow_growth_left,
GrowthInfoLowerBound::kMaxGrowthLeftLowerBound -
lower_bound_growth_left);
- packed_full_growth_info +=
- GetRebalanceIncrement(overflow_to_lower_bound_size);
- little_endian::Store64(full_growth_info, packed_full_growth_info);
- auto result = GetGrowthInfoLowerBoundFromPacked(packed_full_growth_info);
+ SetGrowthInfoOverflow(overflow_growth_left - overflow_to_lower_bound_size);
+ inline_data_.increment_growth_info_lower_bound(overflow_to_lower_bound_size);
+ auto result = GetGrowthInfoLowerBound();
ABSL_SWISSTABLE_ASSERT(result.HasNoDeleted() ==
GetGrowthInfoLowerBound().HasNoDeleted());
ABSL_SWISSTABLE_ASSERT(
(result.GetGrowthLeft() > 0 ||
- GetGrowthLeftTotalBigCapacity(full_growth_info_ptr()) == 0) &&
+ (GetGrowthLeftLowerBound() + GetOverflowGrowthLeft() == 0)) &&
"rebalance may return 0 only if we have absolutely no growth left");
return result;
}
-void GrowthInfoAccessor::OverwriteFullAsEmpty() {
- if (GetGrowthLeftLowerBound() <
- GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
- ++(*growth_info_lower_bound_);
- } else {
- constexpr uint64_t kIncrement = GetPackedIncrement(
- /*lower_bound_increment=*/0, /*overflow_increment=*/1);
- void* const full_growth_info = full_growth_info_ptr();
- little_endian::Store64(
- full_growth_info, little_endian::Load64(full_growth_info) + kIncrement);
- }
-}
-
-void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) {
- ABSL_SWISSTABLE_ASSERT(ctrl[capacity] == ctrl_t::kSentinel);
- ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
- for (ctrl_t* pos = ctrl; pos < ctrl + capacity; pos += Group::kWidth) {
- Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos);
- }
- // Copy the cloned ctrl bytes.
- std::memcpy(ctrl + capacity + 1, ctrl, NumClonedBytes());
- ctrl[capacity] = ctrl_t::kSentinel;
-}
-
-void IterateOverFullSlots(const CommonFields& c, size_t slot_size,
- absl::FunctionRef<void(const ctrl_t*, void*)> cb) {
- IterateOverFullSlotsImpl(c, slot_size, cb);
-}
-
HashtablezInfoHandle CommonFields::infoz_ptr() const {
// growth_info is stored before control bytes.
ABSL_SWISSTABLE_ASSERT(has_infoz());
@@ -465,11 +405,46 @@ void CommonFields::set_infoz(HashtablezInfoHandle infoz) {
}
namespace {
+void DeallocBackingArrayImpl(void* alloc, size_t capacity, ctrl_t* ctrl,
+ size_t slot_size, size_t slot_align,
+ bool has_infoz, size_t blocked_element_count,
+ DeallocBackingArrayFn dealloc) {
+ RawHashSetLayout layout(capacity, slot_size, slot_align, has_infoz,
+ blocked_element_count);
+ void* backing_array = ctrl - layout.control_offset();
+ // Unpoison before returning the memory to the allocator.
+ SanitizerUnpoisonMemoryRegion(backing_array, layout.alloc_size());
+ dealloc(alloc, backing_array, layout.alloc_size());
+}
+
+void DeallocBackingArrayImpl(CommonFields& c,
+ const PolicyFunctions& __restrict policy,
+ void* alloc) {
+ DeallocBackingArrayImpl(alloc, c.capacity(), c.control(), policy.slot_size,
+ policy.slot_align, c.has_infoz(),
+ c.blocked_element_count(), policy.dealloc);
+}
-void ResetGrowthLeft(GrowthInfoAccessor growth_info, size_t capacity,
- size_t occupied_elements) {
- growth_info.InitGrowthLeftNoDeleted(
- CapacityToGrowth(capacity) - occupied_elements, capacity);
+} // namespace
+
+void UnregisterAndDeallocBackingArray(CommonFields& c,
+ const DtorPolicy& __restrict policy,
+ DeallocBackingArrayFn dealloc,
+ void* alloc) {
+ size_t cap = c.capacity(); // capacity is already in register, so storing it
+ // in a local variable before Unregister().
+ c.infoz().Unregister();
+ DeallocBackingArrayImpl(alloc, cap, c.control(), policy.slot_size,
+ policy.slot_align, c.has_infoz(),
+ c.blocked_element_count(), dealloc);
+}
+
+namespace {
+
+void ResetGrowthLeft(size_t capacity, size_t occupied_elements,
+ CommonFields& common) {
+ common.InitGrowthLeftNoDeleted(CapacityToGrowth(capacity) - occupied_elements,
+ capacity);
}
// Finds guaranteed to exists empty slot from the given position.
@@ -696,8 +671,7 @@ void* DropDeletesWithoutResizeAndPrepareInsert(
}
// Prepare insert for the new element.
PrepareInsertCommon(common);
- ResetGrowthLeft(common.growth_info(), capacity,
- common.size() + blocked_element_count);
+ ResetGrowthLeft(capacity, common.size() + blocked_element_count, common);
FindInfo find_info = find_first_non_full(common, new_hash);
SetCtrlInLargeTable(common, find_info.offset, H2(new_hash), slot_size);
common.infoz().RecordInsertMiss(new_hash, find_info.probe_length);
@@ -830,9 +804,7 @@ void ClearBackingArrayNoReuse(CommonFields& c,
c.infoz().RecordClearedReservation();
c.infoz().RecordStorageChanged(0, policy.soo_capacity());
c.infoz().Unregister();
- (*policy.dealloc)(alloc, c.capacity(), c.control(), policy.slot_size,
- policy.slot_align, c.has_infoz(),
- c.blocked_element_count());
+ DeallocBackingArrayImpl(c, policy, alloc);
c = policy.soo_enabled ? CommonFields{soo_tag_t{}}
: CommonFields{non_soo_tag_t{}};
}
@@ -851,6 +823,36 @@ void DecrementSmallSize(CommonFields& c) {
}
}
+void DestructSoo(CommonFields& c, const DtorPolicy& __restrict policy,
+ DeallocBackingArrayFn dealloc, void* alloc) {
+ ABSL_SWISSTABLE_ASSERT(!c.is_small() || !c.empty());
+ if (c.is_small()) {
+ ABSL_SWISSTABLE_ASSERT(policy.destroy_slot != nullptr);
+ policy.destroy_slot(&c, c.soo_data());
+ return;
+ }
+ if (policy.destroy_slot != nullptr) {
+ DestroySlots(c, policy.slot_size, policy.destroy_slot);
+ }
+ UnregisterAndDeallocBackingArray(c, policy, dealloc, alloc);
+}
+
+void DestructNonSoo(CommonFields& c, const DtorPolicy& __restrict policy,
+ DeallocBackingArrayFn dealloc, void* alloc) {
+ ABSL_SWISSTABLE_ASSERT(c.capacity() > 0);
+ if (policy.destroy_slot != nullptr) {
+ if (c.is_small()) {
+ if (!c.empty()) {
+ static_assert(kMaxSmallCapacity == 1);
+ policy.destroy_slot(&c, c.slot_array(/*capacity=*/1));
+ }
+ } else {
+ DestroySlots(c, policy.slot_size, policy.destroy_slot);
+ }
+ }
+ UnregisterAndDeallocBackingArray(c, policy, dealloc, alloc);
+}
+
} // namespace
void EraseMetaOnlySmall(CommonFields& c, bool soo_enabled, size_t slot_size) {
@@ -874,11 +876,11 @@ void EraseMetaOnlyLarge(CommonFields& c, size_t index, size_t slot_size) {
if (WasNeverFull(c, index)) {
SetCtrl(c, index, ctrl_t::kEmpty, slot_size);
- c.growth_info().OverwriteFullAsEmpty();
+ c.OverwriteFullAsEmpty();
return;
}
- c.growth_info().OverwriteFullAsDeleted();
+ c.OverwriteFullAsDeleted();
SetCtrlInLargeTable(c, index, ctrl_t::kDeleted, slot_size);
}
@@ -891,7 +893,7 @@ void ClearBackingArray(CommonFields& c,
c.set_size_to_zero();
ABSL_SWISSTABLE_ASSERT(c.capacity() > policy.soo_capacity());
ResetCtrl(c, policy.slot_size, blocked_element_count);
- ResetGrowthLeft(c.growth_info(), c.capacity(), blocked_element_count);
+ ResetGrowthLeft(c.capacity(), blocked_element_count, c);
ABSL_SWISSTABLE_ASSERT(c.blocked_element_count() == blocked_element_count);
c.infoz().RecordStorageChanged(0, c.capacity());
} else {
@@ -916,14 +918,6 @@ void DestroySlots(CommonFields& c, size_t slot_size,
}
}
-void DeallocBackingArray(CommonFields& c, size_t slot_size, size_t slot_align,
- DeallocBackingArrayFn dealloc, void* alloc) {
- const size_t cap = c.capacity();
- c.infoz().Unregister();
- dealloc(alloc, cap, c.control(), slot_size, slot_align, c.has_infoz(),
- c.blocked_element_count());
-}
-
template <bool kSooEnabled>
void Clear(CommonFields& c, const PolicyFunctions& __restrict policy,
DestroySlotFn destroy_slot, void* alloc) {
@@ -961,36 +955,23 @@ void Clear(CommonFields& c, const PolicyFunctions& __restrict policy,
c.set_reservation_size(0);
}
-void DestructSoo(CommonFields& c, size_t slot_size, size_t slot_align,
- DestroySlotFn destroy_slot, DeallocBackingArrayFn dealloc,
- void* alloc) {
- ABSL_SWISSTABLE_ASSERT(!c.is_small() || !c.empty());
- if (c.is_small()) {
- ABSL_SWISSTABLE_ASSERT(destroy_slot != nullptr);
- destroy_slot(&c, c.soo_data());
- return;
- }
- if (destroy_slot != nullptr) {
- DestroySlots(c, slot_size, destroy_slot);
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& __restrict policy,
+ DeallocBackingArrayFn dealloc, void* alloc) {
+ if constexpr (kSooEnabled) {
+ DestructSoo(c, policy, dealloc, alloc);
+ } else {
+ DestructNonSoo(c, policy, dealloc, alloc);
}
- DeallocBackingArray(c, slot_size, slot_align, dealloc, alloc);
}
-
-void DestructNonSoo(CommonFields& c, size_t slot_size, size_t slot_align,
- DestroySlotFn destroy_slot, DeallocBackingArrayFn dealloc,
- void* alloc) {
- ABSL_SWISSTABLE_ASSERT(c.capacity() > 0);
- if (destroy_slot != nullptr) {
- if (c.is_small()) {
- if (!c.empty()) {
- static_assert(kMaxSmallCapacity == 1);
- destroy_slot(&c, c.slot_array(/*capacity=*/1));
- }
- } else {
- DestroySlots(c, slot_size, destroy_slot);
- }
- }
- DeallocBackingArray(c, slot_size, slot_align, dealloc, alloc);
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& __restrict policy,
+ DeallocBackingArrayFn dealloc) {
+ Destruct<kSooEnabled>(c, policy, dealloc, /*alloc=*/&c);
+}
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& __restrict policy) {
+ Destruct<kSooEnabled>(c, policy, kStandardDeallocBackingArrayFn);
}
namespace {
@@ -1043,8 +1024,6 @@ void ReportGrowthToInfozImpl(CommonFields& common, HashtablezInfoHandle infoz,
infoz.RecordRehash(total_probe_length);
infoz.RecordInsertMiss(hash, distance_from_desired);
common.set_has_infoz();
- // TODO(b/413062340): we could potentially store infoz in place of the
- // control pointer for the capacity 1 case.
common.set_infoz(infoz);
}
@@ -1133,10 +1112,7 @@ void ResizeEmptyNonAllocatedTableImpl(CommonFields& common,
common.generate_new_seed(has_infoz);
ResetCtrl(common, slot_size, blocked_element_count);
- if (GrowthInfoSizeForCapacity(new_capacity) > 0) {
- ResetGrowthLeft(GetGrowthInfoFromControl(new_ctrl), new_capacity,
- blocked_element_count);
- }
+ ResetGrowthLeft(new_capacity, blocked_element_count, common);
if (ABSL_PREDICT_FALSE(has_infoz)) {
ReportResizeToInfoz(common, infoz, 0);
@@ -1218,7 +1194,7 @@ void ResizeFullSooTable(CommonFields& common,
InsertOldSooSlotAndInitializeControlBytes(common, policy, new_ctrl, new_slots,
has_infoz);
- ResetGrowthLeft(common.growth_info(), new_capacity, kTableSize);
+ ResetGrowthLeft(new_capacity, kTableSize, common);
if (has_infoz) {
common.set_has_infoz();
common.set_infoz(infoz);
@@ -1459,10 +1435,7 @@ static_assert(NextCapacity(kMaxLocalBufferNewCapacity) <=
// Initializes mirrored control bytes after
// transfer_unprobed_elements_to_next_capacity.
void InitializeMirroredControlBytes(ctrl_t* new_ctrl, size_t new_capacity) {
- std::memcpy(new_ctrl + new_capacity,
- // We own GrowthInfo just before control bytes. So it is ok
- // to read one byte from it.
- new_ctrl - 1, Group::kWidth);
+ std::memcpy(new_ctrl + new_capacity + 1, new_ctrl, Group::kWidth - 1);
new_ctrl[new_capacity] = ctrl_t::kSentinel;
}
@@ -1757,15 +1730,14 @@ void* Grow1To3AndPrepareInsert(CommonFields& common,
void* new_element_target_slot = SlotAddress(new_slots, offset, slot_size);
SanitizerUnpoisonMemoryRegion(new_element_target_slot, slot_size);
- policy.dealloc(alloc, kOldCapacity,
- // old_slots == old_ctrl in case of capacity == 1.
- static_cast<ctrl_t*>(old_slots),
- slot_size, slot_align, has_infoz,
- /*blocked_element_count=*/0);
+ DeallocBackingArrayImpl(alloc, kOldCapacity,
+ // old_slots == old_ctrl in case of capacity == 1.
+ static_cast<ctrl_t*>(old_slots), slot_size,
+ slot_align, has_infoz,
+ /*blocked_element_count=*/0, policy.dealloc);
PrepareInsertCommon(common);
ABSL_SWISSTABLE_ASSERT(common.size() == 2);
- GetGrowthInfoFromControl(new_ctrl).InitGrowthLeftNoDeleted(kNewCapacity - 2,
- kNewCapacity);
+ common.InitGrowthLeftNoDeleted(kNewCapacity - 2, kNewCapacity);
if (ABSL_PREDICT_FALSE(has_infoz)) {
ReportSingleGroupTableGrowthToInfoz(common, infoz, new_hash);
@@ -1779,8 +1751,7 @@ void* GrowToNextCapacityAndPrepareInsert(
CommonFields& common, const PolicyFunctions& __restrict policy,
size_t new_hash) {
const size_t old_capacity = common.capacity();
- ABSL_SWISSTABLE_ASSERT(
- common.growth_info().GetGrowthLeftTotalSlow(old_capacity) == 0);
+ ABSL_SWISSTABLE_ASSERT(common.GetGrowthLeftTotalSlow(old_capacity) == 0);
ABSL_SWISSTABLE_ASSERT(old_capacity > policy.soo_capacity());
ABSL_SWISSTABLE_ASSERT(!IsSmallCapacity(old_capacity));
ABSL_ASSUME(old_capacity > kMaxSmallCapacity);
@@ -1835,11 +1806,10 @@ void* GrowToNextCapacityAndPrepareInsert(
SetCtrlInLargeTable(common, find_info.offset, new_h2, policy.slot_size);
}
ABSL_SWISSTABLE_ASSERT(old_capacity > policy.soo_capacity());
- (*policy.dealloc)(alloc, old_capacity, old_ctrl, slot_size, slot_align,
- has_infoz, old_blocked_element_count);
+ DeallocBackingArrayImpl(alloc, old_capacity, old_ctrl, slot_size, slot_align,
+ has_infoz, old_blocked_element_count, policy.dealloc);
PrepareInsertCommon(common);
- ResetGrowthLeft(GetGrowthInfoFromControl(new_ctrl), new_capacity,
- common.size());
+ ResetGrowthLeft(new_capacity, common.size(), common);
if (ABSL_PREDICT_FALSE(has_infoz)) {
ReportGrowthToInfoz(common, infoz, new_hash, total_probe_length,
@@ -1907,8 +1877,7 @@ ABSL_ATTRIBUTE_NOINLINE
void* RehashOrGrowToNextCapacityAndPrepareInsert(
CommonFields& common, const PolicyFunctions& __restrict policy,
size_t new_hash) {
- ABSL_SWISSTABLE_ASSERT(
- !common.growth_info().GetGrowthInfoLowerBound().HasNoDeleted());
+ ABSL_SWISSTABLE_ASSERT(!common.GetGrowthInfoLowerBound().HasNoDeleted());
const size_t cap = common.capacity();
ABSL_ASSUME(cap > 0);
// Do these calculations in 64-bit to avoid overflow.
@@ -1968,11 +1937,10 @@ ABSL_ATTRIBUTE_NOINLINE
void* PrepareInsertLargeSlow(CommonFields& common,
const PolicyFunctions& __restrict policy,
size_t hash) {
- GrowthInfoAccessor growth_info = common.growth_info();
const size_t cap = common.capacity();
ABSL_ASSUME(cap > kMaxSmallCapacity);
GrowthInfoLowerBound growth_info_lower_bound =
- growth_info.RebalanceGrowthLeftLowerBound(cap);
+ common.RebalanceGrowthLeftLowerBound(cap);
if (ABSL_PREDICT_TRUE(
growth_info_lower_bound.HasNoGrowthLeftAndNoDeleted())) {
// Table without deleted slots (>95% cases) that needs to be resized.
@@ -1989,7 +1957,7 @@ void* PrepareInsertLargeSlow(CommonFields& common,
// rebalanced.
FindInfo target = find_first_non_full(common, hash);
PrepareInsertCommon(common);
- growth_info.OverwriteControlAsFull(common.control()[target.offset]);
+ common.OverwriteControlAsFull(common.control()[target.offset]);
SetCtrlInLargeTable(common, target.offset, H2(hash), policy.slot_size);
common.infoz().RecordInsertMiss(hash, target.probe_length);
return SlotAddress(common.slot_array(cap), target.offset, policy.slot_size);
@@ -2010,7 +1978,7 @@ GrowEmptySooTableToNextCapacityForceSamplingAndPrepareInsert(
/*blocked_element_count=*/0,
/*force_infoz=*/true);
PrepareInsertCommon(common);
- common.growth_info().OverwriteEmptyAsFull();
+ common.OverwriteEmptyAsFull();
const size_t new_hash = get_hash(common.seed().seed());
SetCtrlInSingleGroupTable(common, SooSlotIndex(), H2(new_hash),
policy.slot_size);
@@ -2131,12 +2099,9 @@ void ResizeAllocatedTableWithSeedChange(
ABSL_SWISSTABLE_ASSERT(old_capacity > 0);
total_probe_length = FindNewPositionsAndTransferSlots(
common, policy, old_ctrl, old_slots, old_capacity);
- (*policy.dealloc)(alloc, old_capacity, old_ctrl, slot_size, slot_align,
- has_infoz, old_blocked_element_count);
- if (GrowthInfoSizeForCapacity(new_capacity) > 0) {
- ResetGrowthLeft(GetGrowthInfoFromControl(new_ctrl), new_capacity,
- common.size());
- }
+ DeallocBackingArrayImpl(alloc, old_capacity, old_ctrl, slot_size, slot_align,
+ has_infoz, old_blocked_element_count, policy.dealloc);
+ ResetGrowthLeft(new_capacity, common.size(), common);
if (ABSL_PREDICT_FALSE(has_infoz)) {
ReportResizeToInfoz(common, infoz, total_probe_length);
@@ -2171,8 +2136,7 @@ void* GrowSooTableToNextCapacityAndPrepareInsert(
PrepareInsertCommon(common);
ABSL_SWISSTABLE_ASSERT(common.size() == 2);
- GetGrowthInfoFromControl(new_ctrl).InitGrowthLeftNoDeleted(kNewCapacity - 2,
- kNewCapacity);
+ common.InitGrowthLeftNoDeleted(kNewCapacity - 2, kNewCapacity);
common.generate_new_seed(/*has_infoz=*/false);
const h2_t soo_slot_h2 = H2(policy.hash_slot(
policy.hash_fn(common), common.soo_data(), common.seed().seed()));
@@ -2338,7 +2302,7 @@ void Copy(CommonFields& common, const PolicyFunctions& __restrict policy,
common.maybe_increment_generation_on_insert();
});
common.increment_size(size);
- ResetGrowthLeft(common.growth_info(), cap, size + blocked_element_count);
+ ResetGrowthLeft(cap, size + blocked_element_count, common);
}
void ReserveTableToFitNewSize(CommonFields& common,
@@ -2357,9 +2321,8 @@ void ReserveTableToFitNewSize(CommonFields& common,
ABSL_SWISSTABLE_ASSERT(!common.empty() || cap > policy.soo_capacity());
ABSL_SWISSTABLE_ASSERT(cap > 0);
const size_t max_size_before_growth =
- IsSmallCapacity(cap)
- ? cap
- : common.size() + common.growth_info().GetGrowthLeftTotalSlow(cap);
+ IsSmallCapacity(cap) ? cap
+ : common.size() + common.GetGrowthLeftTotalSlow(cap);
if (new_size <= max_size_before_growth) {
return;
}
@@ -2373,16 +2336,15 @@ void* PrepareInsertLargeImpl(CommonFields& common,
Group::NonIterableBitMaskType mask_empty,
FindInfo target_group) {
ABSL_SWISSTABLE_ASSERT(!common.is_small());
- GrowthInfoAccessor growth_info = common.growth_info();
// When there are no deleted slots in the table
// and growth_left is positive, we can insert at the first
// empty slot in the probe sequence (target).
if (ABSL_PREDICT_FALSE(
- !growth_info.GetGrowthInfoLowerBound().HasNoDeletedAndGrowthLeft())) {
+ !common.GetGrowthInfoLowerBound().HasNoDeletedAndGrowthLeft())) {
return PrepareInsertLargeSlow(common, policy, hash);
}
PrepareInsertCommon(common);
- growth_info.OverwriteEmptyAsFull();
+ common.OverwriteEmptyAsFull();
const size_t cap = common.capacity();
ABSL_ASSUME(cap > kMaxSmallCapacity);
target_group.offset += mask_empty.LowestBitSet();
@@ -2410,7 +2372,7 @@ void* PrepareInsertLargeGenerationsEnabled(
// NOLINTNEXTLINE(misc-static-assert)
ABSL_SWISSTABLE_ASSERT(SwisstableGenerationsEnabled());
const size_t cap = common.capacity();
- const size_t growth_left = common.growth_info().GetGrowthLeftTotalSlow(cap);
+ const size_t growth_left = common.GetGrowthLeftTotalSlow(cap);
// As an optimization, we avoid calling ShouldRehashForBugDetection if we
// will end up rehashing anyways.
if (growth_left > 0 && common.should_rehash_for_bug_detection_on_insert()) {
@@ -2482,18 +2444,41 @@ template void* GrowSooTableToNextCapacityAndPrepareInsert<
static_assert(MaxSooSlotSize() == 8);
#endif
-template void* AllocateBackingArray<BackingArrayAlignment(alignof(size_t)),
+template void* AllocateBackingArray<kStandardBackingArrayAlignment,
std::allocator<char>>(void* alloc,
size_t n);
-template void DeallocateBackingArray<BackingArrayAlignment(alignof(size_t)),
- std::allocator<char>>(
- void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
- size_t slot_align, bool had_infoz, size_t blocked_element_count);
-
-template void Clear<true>(CommonFields& c, const PolicyFunctions& policy,
- DestroySlotFn destroy_slot, void* alloc);
-template void Clear<false>(CommonFields& c, const PolicyFunctions& policy,
- DestroySlotFn destroy_slot, void* alloc);
+template void DeallocateBackingArray<kStandardBackingArrayAlignment,
+ std::allocator<char>>(void* alloc,
+ void* backing_array,
+ size_t n);
+
+template void Clear</*kSooEnabled=*/true>(CommonFields& c,
+ const PolicyFunctions& policy,
+ DestroySlotFn destroy_slot,
+ void* alloc);
+template void Clear</*kSooEnabled=*/false>(CommonFields& c,
+ const PolicyFunctions& policy,
+ DestroySlotFn destroy_slot,
+ void* alloc);
+
+template void Destruct</*kSooEnabled=*/true>(CommonFields& c,
+ const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc,
+ void* alloc);
+template void Destruct</*kSooEnabled=*/true>(CommonFields& c,
+ const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc);
+template void Destruct</*kSooEnabled=*/true>(CommonFields& c,
+ const DtorPolicy& policy);
+template void Destruct</*kSooEnabled=*/false>(CommonFields& c,
+ const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc,
+ void* alloc);
+template void Destruct</*kSooEnabled=*/false>(CommonFields& c,
+ const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc);
+template void Destruct</*kSooEnabled=*/false>(CommonFields& c,
+ const DtorPolicy& policy);
} // namespace container_internal
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
index ad416cd79b5..ca0e83d3b1f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
@@ -62,10 +62,7 @@
// HashtablezInfoHandle infoz_; // optional
// // Additional number that can be added to growth_left_lower_bound.
// // Only stored for tables with large capacities.
-// uint8_t growth_left_overflow[7]; // optional
-// // The minimum number of elements we can insert before growing the
-// // capacity.
-// uint8_t growth_left_lower_bound;
+// uint64_t growth_left_overflow; // optional
// // Control bytes for the "real" slots.
// ctrl_t ctrl[capacity];
// // Always `ctrl_t::kSentinel`. This is used by iterators to find when to
@@ -204,6 +201,7 @@
#include "absl/base/internal/endian.h"
#include "absl/base/internal/iterator_traits.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/unaligned_access.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/options.h"
@@ -324,6 +322,11 @@ struct IsDecomposable<
std::declval<Ts>()...))>,
Policy, Hash, Eq, Ts...> : std::true_type {};
+template <typename T, template <typename...> class Template>
+struct is_instance_of : std::false_type {};
+template <template <typename...> class Template, typename... Args>
+struct is_instance_of<Template<Args...>, Template> : std::true_type {};
+
ABSL_DLL extern char kDefaultIterSlot;
// Returns a pointer to a control byte that can be used by default-constructed
@@ -651,6 +654,96 @@ class BlockedInfo {
uint8_t tail_blocked_;
};
+// Stored the information regarding number of slots we can still fill
+// without needing to rehash.
+//
+// We want to ensure sufficient number of empty slots in the table in order
+// to keep probe sequences relatively short. Empty slot in the probe group
+// is required to stop probing.
+//
+// Tombstones (kDeleted slots) are not included in the growth capacity,
+// because we'd like to rehash when the table is filled with tombstones and/or
+// full slots.
+//
+// GrowthInfo also stores a bit that encodes whether table may have any
+// deleted slots.
+// Most of the tables (>95%) have no deleted slots, so some functions can
+// be more efficient with this information.
+//
+// Callers can also force a rehash via the standard `rehash(0)`,
+// which will recompute this value as a side-effect.
+//
+// See also `CapacityToGrowth()`.
+//
+// GrowthInfoLowerBound is stored as 8 bits in HashtableInlineData.
+// For capacity > kMaxGrowthLeftLowerBound we additionally store 8 bytes
+// at the beginning of the backing array. Storing GrowthInfoLowerBound in
+// HashtableInlineData helps to avoid any branching in the hottest code
+// accessing GrowthInfo. GrowthInfoLowerBound has 7 bits to store the growth
+// left and 1 bit to store whether the table has any deleted slots. GrowthInfo
+// overflow for capacity > kMaxGrowthLeftLowerBound is stored as unaligned
+// uint64_t.
+
+// One byte encoding of lower bound GrowthInfo.
+// It encodes number of growth left from 0 to kMaxGrowthLeftLowerBound and
+// whether the table has any deleted slots.
+class GrowthInfoLowerBound {
+ public:
+ static constexpr uint8_t kGrowthLeftMask = 0x7Fu;
+ static constexpr uint8_t kDeletedBit = 0x80u;
+ static constexpr size_t kMaxGrowthLeftLowerBound = 127;
+ static_assert(kMaxGrowthLeftLowerBound == kGrowthLeftMask);
+
+ explicit constexpr GrowthInfoLowerBound(uint8_t growth_left)
+ : growth_left_(growth_left) {}
+
+ // Returns the raw one byte encoded value of the GrowthInfoLowerBound.
+ uint8_t ToRawData() const { return growth_left_; }
+
+ // Returns true if table satisfies two properties:
+ // 1. Guaranteed to have no kDeleted slots.
+ // 2. There is a place for at least one element to grow.
+ constexpr bool HasNoDeletedAndGrowthLeft() const {
+ return static_cast<int8_t>(growth_left_) > 0;
+ }
+
+ // Returns true if table satisfies two properties:
+ // 1. May have kDeleted slots (kDeletedBit == 1).
+ // 2. There is a place for at least one element to grow.
+ constexpr bool HasDeletedAndGrowthLeft() const {
+ return growth_left_ > kDeletedBit;
+ }
+
+ // Returns true if the table satisfies two properties:
+ // 1. Guaranteed to have no kDeleted slots.
+ // 2. There is no growth left.
+ constexpr bool HasNoGrowthLeftAndNoDeleted() const {
+ return growth_left_ == 0;
+ }
+
+ // Returns true if GetGrowthLeft() == 0 and HasNoDeleted() is false.
+ // It is slightly more efficient.
+ constexpr bool HasNoGrowthLeftAndHaveDeleted() const {
+ return growth_left_ == kDeletedBit;
+ }
+
+ // Returns true if table guaranteed to have no kDeleted slots.
+ constexpr bool HasNoDeleted() const {
+ return (growth_left_ & kDeletedBit) == 0;
+ }
+
+ // Returns the minimum number of elements left to grow.
+ // Use GrowthInfoView::GetGrowthLeftTotal() to get the total number of
+ // elements left to grow. For tables with capacity <=
+ // kMaxGrowthLeftLowerBound, this is the same as GetGrowthLeftTotal().
+ constexpr uint8_t GetGrowthLeft() const {
+ return growth_left_ & kGrowthLeftMask;
+ }
+
+ private:
+ uint8_t growth_left_;
+};
+
// Capacity, size and also has additionally
// 1) one bit that stores whether we have infoz.
// 2) kBlockedElementsBitCount bits that stores number of blocked elements in
@@ -668,6 +761,7 @@ class HashtableInlineDataImpl {
public:
static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode;
using HashtableCapacity = HashtableCapacityImpl<StorageMode>;
+ static constexpr size_t kGrowthInfoLowerBoundBitCount = 8;
static constexpr size_t kBlockedElementBitCount = 3;
static constexpr size_t kMaxBlockedElementCount =
(uint64_t{1} << kBlockedElementBitCount) - 1;
@@ -676,8 +770,9 @@ class HashtableInlineDataImpl {
static constexpr size_t kCapacityBitStoredInDataCount =
StorageMode == kCapacityByValue ? 0 : kCapacityBitCount;
static constexpr size_t kSizeBitCount =
- 64 - (kBlockedElementBitCount + kSeedBitCount +
- /*has_infoz*/ 1 + kCapacityBitStoredInDataCount);
+ 64 -
+ (kBlockedElementBitCount + kSeedBitCount + kGrowthInfoLowerBoundBitCount +
+ /*has_infoz*/ 1 + kCapacityBitStoredInDataCount);
explicit HashtableInlineDataImpl(uninitialized_tag_t) {}
explicit HashtableInlineDataImpl(HashtableCapacity capacity,
@@ -758,11 +853,63 @@ class HashtableInlineDataImpl {
}
void set_blocked_element_count_to_zero() { data_ &= ~kBlockedElementMask; }
+ GrowthInfoLowerBound growth_info_lower_bound() const {
+ ABSL_SWISSTABLE_ASSERT(!is_small() &&
+ "we do not track growth for small tables");
+ return GrowthInfoLowerBound(static_cast<uint8_t>(
+ (data_ & kGrowthInfoLowerBoundMask) >> kGrowthInfoLowerBoundShift));
+ }
+
+ void set_growth_info_lower_bound(
+ GrowthInfoLowerBound growth_info_lower_bound) {
+ data_ = (data_ & ~kGrowthInfoLowerBoundMask) |
+ (uint64_t{growth_info_lower_bound.ToRawData()}
+ << kGrowthInfoLowerBoundShift);
+ }
+
+ // Overwrites single empty slot with a full slot.
+ // Must be called when growth left lower bound is positive.
+ void overwrite_empty_as_full() {
+ ABSL_SWISSTABLE_ASSERT(growth_info_lower_bound().GetGrowthLeft() > 0);
+ data_ -= kGrowthInfoLowerBoundOne;
+ }
+
+ // Overwrites single full slot with an empty slot.
+ // Must be called when growth left lower bound is less than
+ // kMaxGrowthLeftLowerBound.
+ void overwrite_full_as_empty_in_lower_bound() {
+ increment_growth_info_lower_bound(1);
+ }
+
+ // Increments the growth left lower bound by the given increment.
+ // Must be called when the growth left lower bound + increment does not exceed
+ // kMaxGrowthLeftLowerBound.
+ void increment_growth_info_lower_bound(size_t increment) {
+ ABSL_SWISSTABLE_ASSERT(growth_info_lower_bound().GetGrowthLeft() +
+ increment <=
+ GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
+ data_ += increment << kGrowthInfoLowerBoundShift;
+ }
+
+ // Overwrites specified control element with full slot.
+ // Must be called when growth left lower bound is >= IsEmpty(ctrl).
+ void overwrite_control_as_full(ctrl_t ctrl) {
+ ABSL_SWISSTABLE_ASSERT(growth_info_lower_bound().GetGrowthLeft() >=
+ static_cast<size_t>(IsEmpty(ctrl)));
+ data_ -= static_cast<size_t>(IsEmpty(ctrl)) << kGrowthInfoLowerBoundShift;
+ }
+
+ // Overwrites single full slot with a deleted slot.
+ void overwrite_full_as_deleted() {
+ data_ |= (GrowthInfoLowerBound::kDeletedBit << kGrowthInfoLowerBoundShift);
+ }
+
void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
private:
// Bit layout of `data_` and `capacity_internal_` from MSB to LSB:
- // (55/49 bits) : size
+ // (47/41 bits) : size
+ // (8 bits) : growth_info_lower_bound
// (3 bits) : blocked_element_count
// (1 bit) : has_infoz
// (5 bits) : seed
@@ -770,8 +917,7 @@ class HashtableInlineDataImpl {
// We don't split these components of `data_` into separate bit field elements
// because we get worse generated code that way.
- static constexpr size_t kDataBitCount =
- kSeedBitCount + 1 + kSizeBitCount + kBlockedElementBitCount;
+ static constexpr size_t kDataBitCount = 64 - kCapacityBitStoredInDataCount;
static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount;
static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
@@ -781,6 +927,12 @@ class HashtableInlineDataImpl {
static constexpr uint64_t kBlockedElementsShift = kSeedBitCount + 1;
static constexpr uint64_t kBlockedElementMask = kMaxBlockedElementCount
<< kBlockedElementsShift;
+ static constexpr uint64_t kGrowthInfoLowerBoundShift =
+ kBlockedElementsShift + kBlockedElementBitCount;
+ static constexpr uint64_t kGrowthInfoLowerBoundOne =
+ uint64_t{1} << kGrowthInfoLowerBoundShift;
+ static constexpr uint64_t kGrowthInfoLowerBoundMask =
+ uint64_t{0xff} << kGrowthInfoLowerBoundShift;
// For SOO tables, the seed is unused, and bit 0 is repurposed to track
// whether the table has already queried should_sample_soo().
static constexpr uint64_t kSooHasTriedSamplingMask = 1;
@@ -976,171 +1128,6 @@ using CommonFieldsGenerationInfo = CommonFieldsGenerationInfoDisabled;
using HashSetIteratorGenerationInfo = HashSetIteratorGenerationInfoDisabled;
#endif
-// Stored the information regarding number of slots we can still fill
-// without needing to rehash.
-//
-// We want to ensure sufficient number of empty slots in the table in order
-// to keep probe sequences relatively short. Empty slot in the probe group
-// is required to stop probing.
-//
-// Tombstones (kDeleted slots) are not included in the growth capacity,
-// because we'd like to rehash when the table is filled with tombstones and/or
-// full slots.
-//
-// GrowthInfo also stores a bit that encodes whether table may have any
-// deleted slots.
-// Most of the tables (>95%) have no deleted slots, so some functions can
-// be more efficient with this information.
-//
-// Callers can also force a rehash via the standard `rehash(0)`,
-// which will recompute this value as a side-effect.
-//
-// See also `CapacityToGrowth()`.
-//
-// GrowthInfo is stored as 1 or 8 bytes at the beginning of the backing array.
-// For capacity <= kMaxGrowthLeftLowerBound we store single byte, otherwise we
-// store 8 bytes. Byte before the first control byte for all tables is always
-// used to store GrowthInfoLowerBound. That helps to avoid any branching in the
-// hottest code accessing GrowthInfo. GrowthInfoLowerBound has 7 bits to store
-// the growth left and 1 bit to store whether the table has any deleted slots.
-// For capacity > kMaxGrowthLeftLowerBound we use another 7 bytes to store the
-// full GrowthInfo. GrowthInfo for capacity > kMaxGrowthLeftLowerBound is stored
-// as uint64_t in little endian encoding. Most significant 8 bits (last byte in
-// little endian encoding) contains GrowthInfoLowerBound.
-class GrowthInfoAccessor;
-
-// One byte encoding of lower bound GrowthInfo.
-// It encodes number of growth left from 0 to kMaxGrowthLeftLowerBound and
-// whether the table has any deleted slots.
-class GrowthInfoLowerBound {
- public:
- static constexpr uint8_t kGrowthLeftMask = 0x7Fu;
- static constexpr uint8_t kDeletedBit = 0x80u;
- static constexpr uint64_t kMaxGrowthLeftLowerBound = 127;
- static_assert(kMaxGrowthLeftLowerBound == kGrowthLeftMask);
-
- explicit constexpr GrowthInfoLowerBound(uint8_t growth_left)
- : growth_left_(growth_left) {}
-
- // Returns true if table satisfies two properties:
- // 1. Guaranteed to have no kDeleted slots.
- // 2. There is a place for at least one element to grow.
- constexpr bool HasNoDeletedAndGrowthLeft() const {
- return static_cast<int8_t>(growth_left_) > 0;
- }
-
- // Returns true if table satisfies two properties:
- // 1. May have kDeleted slots (kDeletedBit == 1).
- // 2. There is a place for at least one element to grow.
- constexpr bool HasDeletedAndGrowthLeft() const {
- return growth_left_ > kDeletedBit;
- }
-
- // Returns true if the table satisfies two properties:
- // 1. Guaranteed to have no kDeleted slots.
- // 2. There is no growth left.
- constexpr bool HasNoGrowthLeftAndNoDeleted() const {
- return growth_left_ == 0;
- }
-
- // Returns true if GetGrowthLeft() == 0 and HasNoDeleted() is false.
- // It is slightly more efficient.
- constexpr bool HasNoGrowthLeftAndHaveDeleted() const {
- return growth_left_ == kDeletedBit;
- }
-
- // Returns true if table guaranteed to have no kDeleted slots.
- constexpr bool HasNoDeleted() const {
- return (growth_left_ & kDeletedBit) == 0;
- }
-
- // Returns the minimum number of elements left to grow.
- // Use GrowthInfoView::GetGrowthLeftTotal() to get the total number of
- // elements left to grow. For tables with capacity <=
- // kMaxGrowthLeftLowerBound, this is the same as GetGrowthLeftTotal().
- constexpr uint8_t GetGrowthLeft() const {
- return growth_left_ & kGrowthLeftMask;
- }
-
- private:
- uint8_t growth_left_;
-};
-
-// GrowthInfo is stored in the backing array, and this class provides a simple
-// interface to access and modify it.
-class GrowthInfoAccessor {
- public:
- // GrowthInfoLowerBound is stored in the most significant 8 bits of the
- // full growth info.
- static constexpr uint64_t kLowerBoundShift = 64 - 8;
-
- explicit GrowthInfoAccessor(void* control)
- : growth_info_lower_bound_(reinterpret_cast<uint8_t*>(control) - 1 -
- NumGenerationBytes()) {}
-
- // Initializes the GrowthInfo assuming we can grow `growth_left` elements
- // and there are no kDeleted slots in the table.
- void InitGrowthLeftNoDeleted(size_t growth_left, size_t capacity);
-
- // Returns a GrowthInfoLowerBound object containing the information
- // about minimum growth left.
- // It guarantees that GetGrowthLeft() will be > 0 if GetGrowthLeftTotal() > 0.
- // It may optionally borrow some growth left from the full_growth_info.
- GrowthInfoLowerBound RebalanceGrowthLeftLowerBound(size_t capacity);
-
- // Overwrites single full slot with an empty slot.
- void OverwriteFullAsEmpty();
-
- // Overwrites single empty slot with a full slot.
- // Must be called when GetGrowthLeftLowerBound() > 0.
- void OverwriteEmptyAsFull() {
- ABSL_SWISSTABLE_ASSERT(GetGrowthLeftLowerBound() > 0);
- --(*growth_info_lower_bound_);
- }
-
- // Overwrites specified control element with full slot.
- // Must be called when GetGrowthLeftLowerBound() >= IsEmpty(ctrl).
- void OverwriteControlAsFull(ctrl_t ctrl) {
- ABSL_SWISSTABLE_ASSERT(GetGrowthLeftLowerBound() >=
- static_cast<size_t>(IsEmpty(ctrl)));
- *growth_info_lower_bound_ -= static_cast<size_t>(IsEmpty(ctrl));
- }
-
- // Overwrites single full slot with a deleted slot.
- void OverwriteFullAsDeleted() {
- *growth_info_lower_bound_ |= GrowthInfoLowerBound::kDeletedBit;
- }
-
- // Returns a GrowthInfoLowerBound object containing the information
- // about minimum growth left.
- GrowthInfoLowerBound GetGrowthInfoLowerBound() const {
- return GrowthInfoLowerBound(*growth_info_lower_bound_);
- }
-
- // Returns the minimum number of elements left to grow.
- size_t GetGrowthLeftLowerBound() const {
- return GetGrowthInfoLowerBound().GetGrowthLeft();
- }
-
- // The number of slots we can still fill without needing to rehash.
- // Hot code paths should try to work with
- // growth_info().GetGrowthLeftLowerBound() instead.
- size_t GetGrowthLeftTotalSlow(size_t capacity) const;
-
- private:
- void* full_growth_info_ptr() const { return growth_info_lower_bound_ - 7; }
-
- GrowthInfoLowerBound RebalanceGrowthLeftLowerBoundLargeCapacity();
-
- // Pointer to the GrowthInfoLowerBound data.
- // For large capacities, 7 bytes before this pointer is used to store
- // the full growth info.
- // NOTE: using a pointer here can result in the compiler being forced to
- // assume aliasing can happen. So in hot code paths, we try to work with
- // GrowthInfoLowerBound directly
- uint8_t* growth_info_lower_bound_;
-};
-
// Returns the number of "cloned control bytes".
//
// This is the number of control bytes that are present both at the beginning
@@ -1154,13 +1141,10 @@ constexpr size_t NumControlBytes(size_t capacity) {
}
// Returns the size in bytes table with given capacity use to store GrowthInfo.
-// Returns 0 for small tables that doesn't store GrowthInfo.
+// Returns 0 for small tables that store GrowthInfo in the inline data.
constexpr size_t GrowthInfoSizeForCapacity(size_t capacity) {
- if (IsSmallCapacity(capacity)) {
- return 0;
- }
return capacity <= GrowthInfoLowerBound::kMaxGrowthLeftLowerBound
- ? sizeof(uint8_t)
+ ? 0
: sizeof(uint64_t);
}
@@ -1274,12 +1258,6 @@ union HeapOrSoo {
unsigned char soo_data[MaxSooSlotSize()];
};
-// Returns a reference to the GrowthInfo object stored immediately before
-// `control`.
-inline GrowthInfoAccessor GetGrowthInfoFromControl(ctrl_t* control) {
- return GrowthInfoAccessor(control);
-}
-
// CommonFields hold the fields in raw_hash_set that do not depend
// on template parameters. This allows us to conveniently pass all
// of this state to helper functions as a single argument.
@@ -1409,11 +1387,48 @@ class CommonFields : public CommonFieldsGenerationInfo {
}
bool is_small() const { return inline_data_.is_small(); }
- GrowthInfoAccessor growth_info() const {
- ABSL_SWISSTABLE_ASSERT(GrowthInfoSizeForCapacity(capacity()) > 0);
- return GetGrowthInfoFromControl(control());
+ // Returns the GrowthInfoLowerBound of the table.
+ // This value is used to determine the minimum number of elements that can be
+ // inserted into the table before a rehash is required.
+ GrowthInfoLowerBound GetGrowthInfoLowerBound() const {
+ return inline_data_.growth_info_lower_bound();
+ }
+
+ // Returns the number of growth left in the lower bound of the table.
+ size_t GetGrowthLeftLowerBound() const {
+ return inline_data_.growth_info_lower_bound().GetGrowthLeft();
}
+ // The number of slots we can still fill without needing to rehash.
+ // Hot code paths should try to work with GetGrowthLeftLowerBound() instead.
+ size_t GetGrowthLeftTotalSlow(size_t capacity) const;
+
+ // Initializes the GrowthInfo assuming we can grow `growth_left` elements
+ // and there are no kDeleted slots in the table.
+ void InitGrowthLeftNoDeleted(size_t growth_left, size_t capacity);
+
+ // Modifies the GrowthInfo to mark full element as deleted.
+ void OverwriteFullAsDeleted() { inline_data_.overwrite_full_as_deleted(); }
+
+ // Modifies the GrowthInfo to mark empty element as full.
+ // Requires: GetGrowthLeftLowerBound() > 0.
+ void OverwriteEmptyAsFull() { inline_data_.overwrite_empty_as_full(); }
+
+ // Modifies the control byte to mark the element as full.
+ // Requires: GetGrowthLeftLowerBound() > IsEmpty(ctrl).
+ void OverwriteControlAsFull(ctrl_t ctrl) {
+ inline_data_.overwrite_control_as_full(ctrl);
+ }
+
+ // Modifies the GrowthInfo to mark full element as empty.
+ void OverwriteFullAsEmpty();
+
+ // Returns a GrowthInfoLowerBound object containing the information
+ // about minimum growth left.
+ // It guarantees that GetGrowthLeft() will be > 0 if GetGrowthLeftTotal() > 0.
+ // It may optionally borrow some growth left from the full_growth_info.
+ GrowthInfoLowerBound RebalanceGrowthLeftLowerBound(size_t capacity);
+
bool has_infoz() const { return inline_data_.has_infoz(); }
void set_has_infoz() {
ABSL_SWISSTABLE_ASSERT(inline_data_.is_sampled_seed());
@@ -1509,6 +1524,27 @@ class CommonFields : public CommonFieldsGenerationInfo {
return (size_t{1} << HasInfozShift()) - 1;
}
+ void* GrowthInfoOverflowAddress() const {
+ return reinterpret_cast<void*>(
+ reinterpret_cast<uintptr_t>(control()) -
+ /*growth_info_overflow_size=*/sizeof(uint64_t) - NumGenerationBytes());
+ }
+
+ size_t GetOverflowGrowthLeft() const {
+ ABSL_SWISSTABLE_ASSERT(capacity() >
+ GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
+ return static_cast<size_t>(
+ base_internal::UnalignedLoad64(GrowthInfoOverflowAddress()));
+ }
+
+ void SetGrowthInfoOverflow(size_t overflow) {
+ ABSL_SWISSTABLE_ASSERT(capacity() >
+ GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
+ base_internal::UnalignedStore64(GrowthInfoOverflowAddress(), overflow);
+ }
+
+ GrowthInfoLowerBound RebalanceGrowthLeftLowerBoundLargeCapacity();
+
// We can't assert that SOO is enabled because we don't have SooEnabled(), but
// we assert what we can.
void AssertInSooMode() const {
@@ -1895,6 +1931,9 @@ constexpr bool ShouldSampleHashtablezInfoForAlloc() {
return std::is_same_v<CharAlloc, std::allocator<char>>;
}
+constexpr size_t kStandardBackingArrayAlignment =
+ BackingArrayAlignment(alignof(size_t));
+
// Allocates `n` bytes for a backing array.
template <size_t AlignOfBackingArray, typename Alloc>
void* AllocateBackingArray(void* alloc, size_t n) {
@@ -1902,20 +1941,16 @@ void* AllocateBackingArray(void* alloc, size_t n) {
}
template <size_t AlignOfBackingArray, typename Alloc>
-void DeallocateBackingArray(void* alloc, size_t capacity, ctrl_t* ctrl,
- size_t slot_size, size_t slot_align, bool had_infoz,
- size_t blocked_element_count) {
- RawHashSetLayout layout(capacity, slot_size, slot_align, had_infoz,
- blocked_element_count);
- void* backing_array = ctrl - layout.control_offset();
- // Unpoison before returning the memory to the allocator.
- SanitizerUnpoisonMemoryRegion(backing_array, layout.alloc_size());
- Deallocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), backing_array,
- layout.alloc_size());
+void DeallocateBackingArray(void* alloc, void* backing_array, size_t n) {
+ Deallocate<AlignOfBackingArray>(static_cast<Alloc*>(alloc), backing_array, n);
}
using DeallocBackingArrayFn =
- decltype(&DeallocateBackingArray<8, std::allocator<char>>);
+ decltype(&DeallocateBackingArray<kStandardBackingArrayAlignment,
+ std::allocator<char>>);
+inline constexpr DeallocBackingArrayFn kStandardDeallocBackingArrayFn =
+ &DeallocateBackingArray<kStandardBackingArrayAlignment,
+ std::allocator<char>>;
// PolicyFunctions bundles together some information for a particular
// raw_hash_set<T, ...> instantiation. This information is passed to
@@ -1969,6 +2004,49 @@ struct PolicyFunctions {
}
};
+using DestroySlotFn = void (*)(void* set, void* slot);
+
+// DtorPolicy bundles information for a particular
+// raw_hash_set<T, ...> instantiation that is needed to destroy the set.
+// This is a subset of the fields in PolicyFunctions to avoid bloat of linker
+// input size. Destructor is being instantiated way more often than other
+// functions, so we do not want to include non-destructor related fields.
+struct DtorPolicy {
+ uint32_t slot_size;
+ uint16_t slot_align;
+ DestroySlotFn destroy_slot;
+
+ template <uint32_t kSlotSize, uint16_t kSlotAlign>
+ static const DtorPolicy& GetTrivialDestructRef() {
+ return R<kSlotSize, kSlotAlign>();
+ }
+
+ template <typename SetType>
+ static const DtorPolicy& GetRef() {
+ return R<SetType>();
+ }
+
+ private:
+ // Code below is aimed to optimize linker input size. Destructors are being
+ // instantiated way more often than other functions, so we make a small effort
+ // to minimize the name length of static variables.
+ template <uint32_t kSlotSize, uint16_t kSlotAlign>
+ static const DtorPolicy& R() {
+ static constexpr DtorPolicy p = {kSlotSize, kSlotAlign,
+ /*destroy_slot=*/nullptr};
+ return p;
+ }
+ template <typename SetType>
+ static const DtorPolicy& R() {
+ static constexpr DtorPolicy p = {
+ sizeof(typename SetType::slot_type),
+ alignof(typename SetType::slot_type),
+ SetType::get_destroy_slot_fn(),
+ };
+ return p;
+ }
+};
+
// The following functions are used for calculating the max valid size of the
// table. This is important for security to avoid overflowing size_t when
// calculating the allocation size of the backing array
@@ -2102,8 +2180,6 @@ void ResizeAllocatedTableWithSeedChange(CommonFields& common,
void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,
void* alloc, bool reuse);
-using DestroySlotFn = void (*)(void* set, void* slot);
-
// Destroys all full slots in the backing array.
// REQUIRES: !is_small(c.capacity()).
// REQUIRES: destroy_slot != nullptr.
@@ -2112,31 +2188,31 @@ void DestroySlots(CommonFields& c, size_t slot_size,
// Deallocates the backing array and unregister infoz if necessary.
// REQUIRES: c.capacity > raw_hash_set::DefaultCapacity().
-void DeallocBackingArray(CommonFields& c, size_t slot_size, size_t slot_align,
- DeallocBackingArrayFn dealloc, void* alloc);
+void UnregisterAndDeallocBackingArray(CommonFields& c, const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc,
+ void* alloc);
// Type erased version of raw_hash_set::clear.
template <bool kSooEnabled>
void Clear(CommonFields& c, const PolicyFunctions& policy,
DestroySlotFn destroy_slot, void* alloc);
-// NOTE: Destruct* functions couldn't use PolicyFunctions in order to support
-// incomplete types.
-// TODO(b/515666499): try to use PolicyFunctions since it makes code simpler and
-// binary size smaller.
-
-// Destructs all elements and deallocates the backing array for SOO tables.
+// Destructs all elements and deallocates the backing array tables.
+// For kSooEnabled = true:
// REQUIRES: !c.is_small || !c.empty()
-// REQUIRES: !c.is_small || destroy_slot != nullptr
-void DestructSoo(CommonFields& c, size_t slot_size, size_t slot_align,
- DestroySlotFn destroy_slot, DeallocBackingArrayFn dealloc,
- void* alloc);
-
-// Destructs all elements and deallocates the backing array for non-SOO tables.
+// REQUIRES: !c.is_small || policy.destroy_slot != nullptr
+// For kSooEnabled = false:
// REQUIRES: c.capacity > 0.
-void DestructNonSoo(CommonFields& c, size_t slot_size, size_t slot_align,
- DestroySlotFn destroy_slot, DeallocBackingArrayFn dealloc,
- void* alloc);
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc, void* alloc);
+// REQUIRES: std::is_empty_v<Alloc>
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& policy,
+ DeallocBackingArrayFn dealloc);
+// REQUIRES: std::is_empty_v<Alloc> && dealloc == kStandardDeallocBackingArrayFn
+template <bool kSooEnabled>
+void Destruct(CommonFields& c, const DtorPolicy& policy);
// Type-erased versions of raw_hash_set::erase_meta_only_{small,large}.
void EraseMetaOnlySmall(CommonFields& c, bool soo_enabled, size_t slot_size);
@@ -2271,9 +2347,13 @@ class raw_hash_set {
using slot_type = typename PolicyTraits::slot_type;
- constexpr static bool kIsDefaultHash =
+ constexpr static bool kIsAbslHash =
std::is_same_v<hasher, absl::Hash<key_type>> ||
- std::is_same_v<hasher, absl::container_internal::StringHash>;
+ std::is_same_v<hasher, absl::container_internal::StringHash> ||
+ // TODO(b/384509507): resolve `no header providing
+ // "absl::hash_internal::TransparentHash" is directly included`.
+ // Maybe we should make "internal/hash.h" be a separate library.
+ is_instance_of<hasher, absl::hash_internal::TransparentHash>::value;
// For non-default hashers it is required to have low bits entropy because
// (a) in such cases, the seed is xor'ed with the hash value rather than being
// used as a seed for the hash function, (b) the seed has low bits that are
@@ -2282,14 +2362,8 @@ class raw_hash_set {
// performance optimization for default hashers. For non-default hashers, we
// shift it back.
constexpr static size_t kSeedShift =
- kIsDefaultHash ? 0 : HashtableInlineData::kCapacityBitStoredInDataCount;
-
- // TODO(b/289225379): we could add extra SOO space inside raw_hash_set
- // after CommonFields to allow inlining larger slot_types (e.g. std::string),
- // but it's a bit complicated if we want to support incomplete mapped_type in
- // flat_hash_map. We could potentially do this for flat_hash_set and for an
- // allowlist of `mapped_type`s of flat_hash_map that includes e.g. arithmetic
- // types, strings, cords, and pairs/tuples of allowlisted types.
+ kIsAbslHash ? 0 : HashtableInlineData::kCapacityBitStoredInDataCount;
+
constexpr static bool SooEnabled() {
return PolicyTraits::soo_enabled() &&
sizeof(slot_type) <= sizeof(HeapOrSoo) &&
@@ -3332,6 +3406,7 @@ class raw_hash_set {
HashtableDebugAccess;
friend struct absl::container_internal::HashtableFreeFunctionsAccess;
+ friend DtorPolicy;
struct FindElement {
template <class K, class... Args>
@@ -3457,30 +3532,33 @@ class raw_hash_set {
DestroySlots(common(), sizeof(slot_type), get_destroy_slot_fn());
}
- void dealloc() {
- ABSL_SWISSTABLE_ASSERT(capacity() > DefaultCapacity());
- DeallocBackingArray(common(), sizeof(slot_type), alignof(slot_type),
- get_dealloc_backing_array_fn(), &char_alloc_ref());
- }
-
void destructor_impl() {
if (SwisstableGenerationsEnabled() &&
maybe_invalid_capacity().IsMovedFrom()) {
return;
}
+ constexpr bool kIsStandardBackingArrayAlignment =
+ std::is_same_v<CharAlloc, std::allocator<char>> &&
+ BackingArrayAlignment(alignof(slot_type)) ==
+ kStandardBackingArrayAlignment;
if constexpr (SooEnabled()) {
if (is_small() &&
(PolicyTraits::template destroy_is_trivial<Alloc>() || empty())) {
return;
}
- DestructSoo(common(), sizeof(slot_type), alignof(slot_type),
- get_destroy_slot_fn(), get_dealloc_backing_array_fn(),
- &char_alloc_ref());
} else {
if (capacity() == 0) return;
- DestructNonSoo(common(), sizeof(slot_type), alignof(slot_type),
- get_destroy_slot_fn(), get_dealloc_backing_array_fn(),
- &char_alloc_ref());
+ }
+ if constexpr (std::is_empty_v<Alloc>) {
+ if constexpr (kIsStandardBackingArrayAlignment) {
+ Destruct<SooEnabled()>(common(), GetDtorPolicy());
+ } else {
+ Destruct<SooEnabled()>(common(), GetDtorPolicy(),
+ get_dealloc_backing_array_fn());
+ }
+ } else {
+ Destruct<SooEnabled()>(common(), GetDtorPolicy(),
+ get_dealloc_backing_array_fn(), &char_alloc_ref());
}
}
@@ -3514,13 +3592,13 @@ class raw_hash_set {
}
template <class K>
ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(const K& key) const {
- return HashElement<hasher, kIsDefaultHash, kSeedShift>{
+ return HashElement<hasher, kIsAbslHash, kSeedShift>{
hash_ref(), common().seed().seed()}(key);
}
ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(slot_type* slot) const {
return PolicyTraits::apply(
- HashElement<hasher, kIsDefaultHash, kSeedShift>{hash_ref(),
- common().seed().seed()},
+ HashElement<hasher, kIsAbslHash, kSeedShift>{hash_ref(),
+ common().seed().seed()},
PolicyTraits::element(slot));
}
@@ -3609,7 +3687,11 @@ class raw_hash_set {
insert(std::move(PolicyTraits::element(it.slot())));
that.destroy(it.slot());
}
- if (!that.is_soo()) that.dealloc();
+ if (!that.is_soo()) {
+ UnregisterAndDeallocBackingArray(that.common(), that.GetDtorPolicy(),
+ that.get_dealloc_backing_array_fn(),
+ &that.char_alloc_ref());
+ }
that.common() = CommonFields::CreateDefault<SooEnabled()>();
annotate_for_bug_detection_on_move(that);
return *this;
@@ -3661,7 +3743,7 @@ class raw_hash_set {
: 0,
kUseMemcpy>(
common(), GetPolicyFunctions(),
- HashKey<hasher, K, kIsDefaultHash, kSeedShift>{hash_ref(), key},
+ HashKey<hasher, K, kIsAbslHash, kSeedShift>{hash_ref(), key},
force_sampling));
return {slot, true};
}
@@ -3678,11 +3760,10 @@ class raw_hash_set {
return {single_slot(), false};
}
}
- return {
- to_slot(PrepareInsertSmallNonSoo(
- common(), GetPolicyFunctions(),
- HashKey<hasher, K, kIsDefaultHash, kSeedShift>{hash_ref(), key})),
- true};
+ return {to_slot(PrepareInsertSmallNonSoo(
+ common(), GetPolicyFunctions(),
+ HashKey<hasher, K, kIsAbslHash, kSeedShift>{hash_ref(), key})),
+ true};
}
template <class K>
@@ -3714,7 +3795,7 @@ class raw_hash_set {
? PrepareInsertLargeGenerationsEnabled(
common(), GetPolicyFunctions(), hash, mask_empty,
FindInfo{target_group_offset, seq.index()},
- HashKey<hasher, K, kIsDefaultHash, kSeedShift>{
+ HashKey<hasher, K, kIsAbslHash, kSeedShift>{
hash_ref(), key})
: PrepareInsertLarge(
common(), GetPolicyFunctions(), hash, mask_empty,
@@ -3834,8 +3915,6 @@ class raw_hash_set {
private:
friend struct RawHashSetTestOnlyAccess;
- GrowthInfoAccessor growth_info() const { return common().growth_info(); }
-
// Prefetch the heap-allocated memory region to resolve potential TLB and
// cache misses. This is intended to overlap with execution of calculating the
// hash for a key.
@@ -3997,6 +4076,21 @@ class raw_hash_set {
CharAlloc>;
}
+ static const DtorPolicy& GetDtorPolicy() {
+ static_assert(sizeof(slot_type) <= (std::numeric_limits<uint32_t>::max)(),
+ "Slot size is too large. Use std::unique_ptr for value type "
+ "or use absl::node_hash_{map,set}.");
+ static_assert(alignof(slot_type) <=
+ size_t{(std::numeric_limits<uint16_t>::max)()});
+ if constexpr (PolicyTraits::template destroy_is_trivial<Alloc>()) {
+ return DtorPolicy::GetTrivialDestructRef<
+ static_cast<uint32_t>(sizeof(slot_type)),
+ static_cast<uint16_t>(alignof(slot_type))>();
+ } else {
+ return DtorPolicy::GetRef<raw_hash_set>();
+ }
+ }
+
static const PolicyFunctions& GetPolicyFunctions() {
static_assert(sizeof(slot_type) <= (std::numeric_limits<uint32_t>::max)(),
"Slot size is too large. Use std::unique_ptr for value type "
@@ -4019,7 +4113,7 @@ class raw_hash_set {
// for standard layout and alignof(Hash) <= alignof(CommonFields).
std::is_empty_v<hasher> ? &GetRefForEmptyClass
: &raw_hash_set::get_hash_ref_fn,
- PolicyTraits::template get_hash_slot_fn<hasher, kIsDefaultHash,
+ PolicyTraits::template get_hash_slot_fn<hasher, kIsAbslHash,
kSeedShift>(),
PolicyTraits::transfer_uses_memcpy()
? TransferNRelocatable<sizeof(slot_type)>
@@ -4033,8 +4127,8 @@ class raw_hash_set {
}
// Bundle together CommonFields plus other objects which might be empty.
- // CompressedTuple will ensure that sizeof is not affected by any of the empty
- // fields that occur after CommonFields.
+ // CompressedTuple will ensure that sizeof is not affected by any of the
+ // empty fields that occur after CommonFields.
absl::container_internal::CompressedTuple<CommonFields, hasher, key_equal,
CharAlloc>
settings_{CommonFields::CreateDefault<SooEnabled()>(), hasher{},
@@ -4125,7 +4219,7 @@ struct HashtableDebugAccess<Set, std::void_t<typename Set::raw_hash_set>> {
using Traits = typename Set::PolicyTraits;
using Slot = typename Traits::slot_type;
- constexpr static bool kIsDefaultHash = Set::kIsDefaultHash;
+ constexpr static bool kIsAbslHash = Set::kIsAbslHash;
static size_t GetNumProbes(const Set& set,
const typename Set::key_type& key) {
@@ -4185,19 +4279,36 @@ extern template void* GrowSooTableToNextCapacityAndPrepareInsert<8, true>(
bool);
#endif
-extern template void* AllocateBackingArray<
- BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(void* alloc,
- size_t n);
-extern template void DeallocateBackingArray<
- BackingArrayAlignment(alignof(size_t)), std::allocator<char>>(
- void* alloc, size_t capacity, ctrl_t* ctrl, size_t slot_size,
- size_t slot_align, bool had_infoz, size_t blocked_element_count);
-
-extern template void Clear<true>(CommonFields& c, const PolicyFunctions& policy,
- DestroySlotFn destroy_slot, void* alloc);
-extern template void Clear<false>(CommonFields& c,
- const PolicyFunctions& policy,
- DestroySlotFn destroy_slot, void* alloc);
+extern template void* AllocateBackingArray<kStandardBackingArrayAlignment,
+ std::allocator<char>>(void* alloc,
+ size_t n);
+extern template void
+DeallocateBackingArray<kStandardBackingArrayAlignment, std::allocator<char>>(
+ void* alloc, void* backing_array, size_t n);
+
+extern template void Clear</*kSooEnabled=*/true>(CommonFields& c,
+ const PolicyFunctions& policy,
+ DestroySlotFn destroy_slot,
+ void* alloc);
+extern template void Clear</*kSooEnabled=*/false>(CommonFields& c,
+ const PolicyFunctions& policy,
+ DestroySlotFn destroy_slot,
+ void* alloc);
+
+extern template void Destruct</*kSooEnabled=*/true>(
+ CommonFields& c, const DtorPolicy& policy, DeallocBackingArrayFn dealloc,
+ void* alloc);
+extern template void Destruct</*kSooEnabled=*/true>(
+ CommonFields& c, const DtorPolicy& policy, DeallocBackingArrayFn dealloc);
+extern template void Destruct</*kSooEnabled=*/true>(CommonFields& c,
+ const DtorPolicy& policy);
+extern template void Destruct</*kSooEnabled=*/false>(
+ CommonFields& c, const DtorPolicy& policy, DeallocBackingArrayFn dealloc,
+ void* alloc);
+extern template void Destruct</*kSooEnabled=*/false>(
+ CommonFields& c, const DtorPolicy& policy, DeallocBackingArrayFn dealloc);
+extern template void Destruct</*kSooEnabled=*/false>(CommonFields& c,
+ const DtorPolicy& policy);
} // namespace container_internal
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc
index 4c0a78a2b67..fccdb48f4df 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_benchmark.cc
@@ -17,7 +17,10 @@
#include <cmath>
#include <cstddef>
#include <cstdint>
+#include <deque>
+#include <functional>
#include <limits>
+#include <memory>
#include <numeric>
#include <random>
#include <string>
@@ -26,12 +29,16 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h"
+#include "absl/container/internal/hashtable_control_bytes.h"
#include "absl/container/internal/raw_hash_set.h"
+#include "absl/hash/hash.h"
#include "absl/random/random.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
#include "benchmark/benchmark.h"
namespace absl {
@@ -69,6 +76,38 @@ struct IntPolicy {
return std::forward<F>(f)(x, x);
}
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
+ static constexpr HashSlotFn get_hash_slot_fn() {
+ return nullptr;
+ }
+};
+
+struct IntArrayPolicy {
+ using slot_type = std::array<int64_t, 3>;
+ using key_type = std::array<int64_t, 3>;
+ using init_type = std::array<int64_t, 3>;
+
+ using DefaultHash = void;
+ using DefaultEq = void;
+ using DefaultAlloc = void;
+
+ static void construct(void*, slot_type* slot, const init_type& v) {
+ *slot = v;
+ }
+ static std::true_type destroy(void*, slot_type*) { return std::true_type{}; }
+ static std::true_type transfer(void*, slot_type* new_slot,
+ slot_type* old_slot) {
+ *new_slot = *old_slot;
+ return std::true_type{};
+ }
+
+ static slot_type& element(slot_type* slot) { return *slot; }
+
+ template <class F>
+ static auto apply(F&& f, slot_type x) -> decltype(std::forward<F>(f)(x, x)) {
+ return std::forward<F>(f)(x, x);
+ }
+
template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
@@ -136,7 +175,7 @@ class StringPolicy {
PairArgs(std::forward<Args>(args)...));
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -152,7 +191,18 @@ struct StringEq : std::equal_to<absl::string_view> {
struct StringTable
: raw_hash_set<StringPolicy, StringHash, StringEq, std::allocator<int>> {
using Base = typename StringTable::raw_hash_set;
- StringTable() {}
+ StringTable() = default;
+ using Base::Base;
+};
+
+struct IntArrayTable
+ : raw_hash_set<
+ IntArrayPolicy,
+ container_internal::hash_default_hash<std::array<int64_t, 3>>,
+ std::equal_to<std::array<int64_t, 3>>,
+ std::allocator<std::array<int64_t, 3>>> {
+ using Base = typename IntArrayTable::raw_hash_set;
+ IntArrayTable() = default;
using Base::Base;
};
@@ -160,7 +210,34 @@ struct IntTable
: raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
std::equal_to<int64_t>, std::allocator<int64_t>> {
using Base = typename IntTable::raw_hash_set;
- IntTable() {}
+ IntTable() = default;
+ using Base::Base;
+};
+
+struct MyInt {
+ int64_t value;
+
+ template <typename H>
+ friend H AbslHashValue(H h, const MyInt& x) {
+ return H::combine(std::move(h), x.value);
+ }
+};
+
+using TransparentIntHash = absl::TransparentHash<int64_t, MyInt>;
+
+struct TransparentIntEq {
+ using is_transparent = void;
+ bool operator()(int64_t x, MyInt y) const { return x == y.value; }
+ bool operator()(MyInt x, MyInt y) const { return x.value == y.value; }
+ bool operator()(MyInt x, int64_t y) const { return x.value == y; }
+ bool operator()(int64_t x, int64_t y) const { return x == y; }
+};
+
+struct TransparentIntTable
+ : raw_hash_set<IntPolicy, TransparentIntHash, TransparentIntEq,
+ std::allocator<int64_t>> {
+ using Base = typename TransparentIntTable::raw_hash_set;
+ TransparentIntTable() = default;
using Base::Base;
};
@@ -455,6 +532,27 @@ BENCHMARK(BM_ReserveIntTable)
->Arg(256)
->Arg(512);
+// value_type is trivially destructible, so the benchmark isn't measuring
+// ~value_type() time.
+void BM_DestructNonSooTableOneElement(benchmark::State& state) {
+ constexpr size_t kBatchSize = 1024;
+ constexpr size_t kReserveSize = 1;
+
+ std::vector<IntArrayTable> tables;
+ while (state.KeepRunningBatch(kBatchSize)) {
+ benchmark::DoNotOptimize(tables);
+ state.PauseTiming();
+ tables.resize(kBatchSize);
+ for (auto& t : tables) {
+ t.reserve(kReserveSize);
+ }
+ state.ResumeTiming();
+ benchmark::DoNotOptimize(tables);
+ tables.clear();
+ }
+}
+BENCHMARK(BM_DestructNonSooTableOneElement);
+
void BM_ReserveStringTable(benchmark::State& state) {
constexpr size_t kBatchSize = 1024;
size_t reserve_size = static_cast<size_t>(state.range(0));
@@ -594,6 +692,20 @@ void BM_DropDeletes(benchmark::State& state) {
}
BENCHMARK(BM_DropDeletes);
+void BM_TransparentFind(benchmark::State& state) {
+ TransparentIntTable table;
+ for (int i = 0; i < 10000; ++i) {
+ table.insert(i);
+ }
+ while (state.KeepRunningBatch(10000)) {
+ for (int i = 0; i < 10000; ++i) {
+ auto it = table.find(MyInt{i});
+ benchmark::DoNotOptimize(it);
+ }
+ }
+}
+BENCHMARK(BM_TransparentFind);
+
void BM_Resize(benchmark::State& state) {
// For now just measure a small cheap hash table since we
// are mostly interested in the overhead of type-erasure
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc
index fee9531aca3..890e40e5b62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_probe_benchmark.cc
@@ -81,7 +81,7 @@ struct Policy {
return std::forward<F>(f)(arg, arg);
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr auto get_hash_slot_fn() {
return nullptr;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
index ec5ec30495f..cc252b4b2e9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
@@ -158,8 +158,7 @@ void VerifyMiddleSizeTableLayout(size_t capacity, size_t slot_size,
ASSERT_LE(capacity, GrowthInfoLowerBound::kMaxGrowthLeftLowerBound);
RawHashSetLayout layout(capacity, slot_size, slot_align, has_infoz,
blocked_element_count);
- EXPECT_EQ(layout.control_offset(),
- /*growth*/ 1 + padding + NumGenerationBytes());
+ EXPECT_EQ(layout.control_offset(), padding + NumGenerationBytes());
size_t expected_slot_offset =
layout.control_offset() + NumControlBytes(capacity);
EXPECT_LT(padding, slot_align);
@@ -171,18 +170,22 @@ void VerifyMiddleSizeTableLayout(size_t capacity, size_t slot_size,
}
TEST(RawHashSetLayout, MiddleSize) {
+ VerifyMiddleSizeTableLayout(/*capacity=*/3, /*slot_size=*/4,
+ /*slot_align=*/1, /*has_infoz=*/false,
+ /*blocked_element_count=*/1,
+ /*padding=*/0);
VerifyMiddleSizeTableLayout(/*capacity=*/3, /*slot_size=*/4,
/*slot_align=*/4, /*has_infoz=*/false,
/*blocked_element_count=*/1,
- /*padding=*/NumGenerationBytes() == 0 ? 0 : 3);
+ /*padding=*/NumGenerationBytes() == 0 ? 1 : 0);
VerifyMiddleSizeTableLayout(/*capacity=*/7, /*slot_size=*/4,
/*slot_align=*/4, /*has_infoz=*/false,
/*blocked_element_count=*/1,
- /*padding=*/NumGenerationBytes() == 0 ? 0 : 3);
+ /*padding=*/NumGenerationBytes() == 0 ? 1 : 0);
VerifyMiddleSizeTableLayout(/*capacity=*/127, /*slot_size=*/8,
/*slot_align=*/8, /*has_infoz=*/false,
/*blocked_element_count=*/3,
- /*padding=*/NumGenerationBytes() == 0 ? 0 : 7);
+ /*padding=*/NumGenerationBytes() == 0 ? 1 : 0);
}
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
@@ -310,17 +313,22 @@ class GrowthInfoAllocator {
public:
explicit GrowthInfoAllocator(size_t capacity) {
if (capacity <= GrowthInfoLowerBound::kMaxGrowthLeftLowerBound) {
- SanitizerPoisonMemoryRegion(control_.data(), 7);
+ SanitizerPoisonMemoryRegion(control_.data(), 8);
}
SanitizerPoisonMemoryRegion(control_.data() + kControlStart, 1);
if constexpr (NumGenerationBytes() > 0) {
- SanitizerPoisonMemoryRegion(
- control_.data() + kControlStart + NumGenerationBytes(),
- NumGenerationBytes());
+ SanitizerPoisonMemoryRegion(control_.data() + 8, NumGenerationBytes());
}
+ common_fields_.set_capacity(capacity);
+ common_fields_.set_control(control_.data() + kControlStart);
+ }
+
+ ~GrowthInfoAllocator() {
+ SanitizerUnpoisonMemoryRegion(control_.data(), control_.size());
}
- GrowthInfoAccessor* operator->() { return &growth_info_; }
+ CommonFields* operator->() { return &common_fields_; }
+ const CommonFields* operator->() const { return &common_fields_; }
private:
static constexpr size_t kControlStart = 8 + NumGenerationBytes();
@@ -328,8 +336,7 @@ class GrowthInfoAllocator {
// on stack.
std::vector<ctrl_t> control_ = std::vector<ctrl_t>(
9 + NumGenerationBytes(), /*garbage*/ ctrl_t::kSentinel);
- GrowthInfoAccessor growth_info_ =
- GrowthInfoAccessor(control_.data() + kControlStart);
+ CommonFields common_fields_ = CommonFields(non_soo_tag_t{});
};
TEST(GrowthInfoViewTest, GetGrowthLeft) {
@@ -489,7 +496,7 @@ TEST(GrowthInfoViewTest, HasDeletedAndGrowthLeft) {
}
TEST(GrowthInfoViewTest, BigCapacityGrowthOverflow) {
- constexpr size_t kCapacity = 256;
+ constexpr size_t kCapacity = 255;
for (bool has_deleted : {true, false}) {
SCOPED_TRACE(testing::Message() << "has_deleted: " << has_deleted);
GrowthInfoAllocator growth_info(kCapacity);
@@ -526,7 +533,7 @@ TEST(GrowthInfoViewTest, BigCapacityGrowthOverflow) {
}
TEST(GrowthInfoViewTest, RebalanceOnInsert) {
- constexpr size_t kCapacity = 512;
+ constexpr size_t kCapacity = 511;
constexpr size_t kOrigGrowthLeft = 260;
for (bool has_deleted : {false, true}) {
SCOPED_TRACE(testing::Message() << "has_deleted: " << has_deleted);
@@ -835,7 +842,7 @@ TYPED_TEST(HashtableDataTest, HashtableInlineDataSize) {
EXPECT_EQ(data.size(), 5);
constexpr size_t kHugeIncrement =
- (size_t(1) << (sizeof(size_t) == 4 ? 31 : 42));
+ (size_t(1) << (sizeof(size_t) == 4 ? 31 : 39));
data.increment_size(kHugeIncrement);
EXPECT_EQ(data.size(), kHugeIncrement + 5);
@@ -1015,7 +1022,7 @@ struct ValuePolicy {
std::forward<F>(f), std::forward<Args>(args)...);
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -1169,7 +1176,7 @@ class StringPolicy {
PairArgs(std::forward<Args>(args)...));
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -1643,7 +1650,6 @@ TEST(Table,
// We want to test codepath deciding whether to rehash in place or not.
// For this we need to potentially have tombstone.
EXPECT_FALSE(RawHashSetTestOnlyAccess::GetCommon(t)
- .growth_info()
.GetGrowthInfoLowerBound()
.HasNoDeleted());
for (int64_t i = static_cast<int64_t>(Group::kWidth);
@@ -2802,6 +2808,11 @@ struct DecomposeType {
return *this;
}
+ template <typename H>
+ friend H AbslHashValue(H h, const DecomposeType& d) {
+ return H::combine(std::move(h), d.i);
+ }
+
int i;
};
@@ -2844,7 +2855,7 @@ struct DecomposePolicy {
return std::forward<F>(f)(x, x);
}
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -2994,6 +3005,8 @@ TEST(Table, Decompose) {
TestDecompose<TransparentHashIntOverload, DecomposeEq>(true);
TestDecompose<TransparentHashIntOverload, TransparentEqIntOverload>(true);
TestDecompose<DecomposeHash, TransparentEqIntOverload>(true);
+ TestDecompose<absl::TransparentHash<DecomposeType, int>,
+ TransparentEqIntOverload>(true);
}
struct Modulo1000Hash {
@@ -3452,19 +3465,16 @@ TEST(Table, GrowthInfoDeletedBit) {
t.insert(i);
}
EXPECT_TRUE(RawHashSetTestOnlyAccess::GetCommon(t)
- .growth_info()
.GetGrowthInfoLowerBound()
.HasNoDeleted());
t.erase(0);
EXPECT_EQ(RawHashSetTestOnlyAccess::CountTombstones(t), 1);
EXPECT_FALSE(RawHashSetTestOnlyAccess::GetCommon(t)
- .growth_info()
.GetGrowthInfoLowerBound()
.HasNoDeleted());
t.rehash(0);
EXPECT_EQ(RawHashSetTestOnlyAccess::CountTombstones(t), 0);
EXPECT_TRUE(RawHashSetTestOnlyAccess::GetCommon(t)
- .growth_info()
.GetGrowthInfoLowerBound()
.HasNoDeleted());
}
@@ -5085,7 +5095,7 @@ TEST(Table, MovedFromCallsFail) {
}
{
- ABSL_ATTRIBUTE_UNUSED IntTable t1, t2, t3;
+ [[maybe_unused]] IntTable t1, t2, t3;
t1.insert(1);
t2 = std::move(t1);
// NOLINTNEXTLINE(bugprone-use-after-move)
@@ -5104,9 +5114,9 @@ TEST(Table, MovedFromCallsFail) {
EXPECT_DEATH_IF_SUPPORTED(t1.size(), "moved-from");
}
{
- ABSL_ATTRIBUTE_UNUSED IntTable t1;
+ [[maybe_unused]] IntTable t1;
t1.insert(1);
- ABSL_ATTRIBUTE_UNUSED IntTable t2(std::move(t1));
+ [[maybe_unused]] IntTable t2(std::move(t1));
// NOLINTNEXTLINE(bugprone-use-after-move)
EXPECT_DEATH_IF_SUPPORTED(t1.contains(1), "moved-from");
t1.clear(); // Clearing a moved-from table is allowed.
@@ -5114,7 +5124,7 @@ TEST(Table, MovedFromCallsFail) {
{
// Test that using a table (t3) that was moved-to from a moved-from table
// (t1) fails.
- ABSL_ATTRIBUTE_UNUSED IntTable t1, t2, t3;
+ [[maybe_unused]] IntTable t1, t2, t3;
t1.insert(1);
t2 = std::move(t1);
// NOLINTNEXTLINE(bugprone-use-after-move)
@@ -5202,6 +5212,34 @@ struct ZeroHash {
}
};
+// We use unaligned value to verify that no padding is accidentally used during
+// growth.
+class UnalignedInt32 {
+ public:
+ UnalignedInt32() = default;
+ UnalignedInt32(uint32_t x) { // NOLINT: implicit conversion
+ std::memcpy(x_, &x, sizeof(uint32_t));
+ }
+
+ bool operator==(UnalignedInt32 other) const {
+ return static_cast<uint32_t>(*this) == static_cast<uint32_t>(other);
+ }
+ bool operator==(uint32_t other) const {
+ return static_cast<uint32_t>(*this) == other;
+ }
+ operator uint32_t() const { // NOLINT: implicit conversion
+ uint32_t result;
+ std::memcpy(&result, x_, 4);
+ return result;
+ }
+
+ private:
+ uint8_t x_[4];
+};
+
+static_assert(sizeof(UnalignedInt32) == 4);
+static_assert(alignof(UnalignedInt32) == 1);
+
// This test is imitating growth of a very big table and triggers all buffer
// overflows.
// We try to insert all elements into the first probe group.
@@ -5226,7 +5264,7 @@ TEST(Table, GrowExtremelyLargeTable) {
NextCapacity(ProbedItem8Bytes::kMaxNewCapacity);
#endif
- absl::flat_hash_set<uint32_t, ZeroHash> t(63);
+ absl::flat_hash_set<UnalignedInt32, ZeroHash> t(21);
CommonFields& common = RawHashSetTestOnlyAccess::GetCommon(t);
// Set 0 seed so that H1 is always 0.
common.set_no_seed_for_testing();
@@ -5244,8 +5282,7 @@ TEST(Table, GrowExtremelyLargeTable) {
ASSERT_EQ(t.capacity(), cap);
// Block upto 100 elements to test that kMarkedForSlowTransfer elements do
// not conflict with blocked elements.
- for (size_t i = cap - 1,
- growth_left = common.growth_info().GetGrowthLeftTotalSlow(cap),
+ for (size_t i = cap - 1, growth_left = common.GetGrowthLeftTotalSlow(cap),
blocked = 0;
i > cap / 2; --i) {
if (common.control()[i] == ctrl_t::kEmpty && growth_left > 1) {
@@ -5257,7 +5294,7 @@ TEST(Table, GrowExtremelyLargeTable) {
}
// Update growth info to force resize on the next insert. This way we avoid
// having to insert many elements.
- common.growth_info().InitGrowthLeftNoDeleted(/*growth_left=*/0, cap);
+ common.InitGrowthLeftNoDeleted(/*growth_left=*/0, cap);
t.insert(inserted_till++);
ASSERT_EQ(t.capacity(), NextCapacity(cap));
for (uint8_t i = 0; i < inserted_till; ++i) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc
index f9947f0475d..03ec4107721 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.cc
@@ -14,6 +14,8 @@
#include "absl/container/internal/test_instance_tracker.h"
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace test_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h
index 5ff6fd714e2..52aa392c592 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker.h
@@ -17,7 +17,9 @@
#include <cstdlib>
#include <ostream>
+#include <utility>
+#include "absl/base/config.h"
#include "absl/types/compare.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc
index 1c6a4fa7150..58f1bfb102b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/test_instance_tracker_test.cc
@@ -14,6 +14,8 @@
#include "absl/container/internal/test_instance_tracker.h"
+#include <utility>
+
#include "gtest/gtest.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h
index 1076aea7a6c..fcbcbd9c4d6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h
@@ -16,6 +16,8 @@
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
#include <algorithm>
+#include <cstddef>
+#include <initializer_list>
#include <unordered_map>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h
index ba037c0563f..7015e5d4b38 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h
@@ -15,8 +15,11 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_LOOKUP_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_LOOKUP_TEST_H_
+#include <vector>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/hash_policy_testing.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_members_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_members_test.h
index e9f4979512a..76b1449e2a0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_members_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_members_test.h
@@ -15,9 +15,14 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_
+#include <cstddef>
+#include <memory>
#include <type_traits>
+#include <utility>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h
index bb41e07ba76..aaaae3ff7b4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h
@@ -15,11 +15,14 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_
+#include <cstddef>
#include <memory>
#include <type_traits>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/hash_policy_testing.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_test.cc
index 9cbf512f32b..64685dbd1c7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_map_test.cc
@@ -13,8 +13,13 @@
// limitations under the License.
#include <memory>
+#include <string>
#include <unordered_map>
+#include <utility>
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/container/internal/hash_policy_testing.h"
#include "absl/container/internal/unordered_map_constructor_test.h"
#include "absl/container/internal/unordered_map_lookup_test.h"
#include "absl/container/internal/unordered_map_members_test.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h
index 7038a0c8b2c..47b59f346e2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h
@@ -16,6 +16,8 @@
#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_
#include <algorithm>
+#include <cstddef>
+#include <initializer_list>
#include <unordered_set>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h
index 932c320daf8..9b50cf816f9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h
@@ -15,8 +15,12 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_LOOKUP_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_LOOKUP_TEST_H_
+#include <type_traits>
+#include <vector>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/hash_policy_testing.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_members_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_members_test.h
index b416fef4d78..34d9e697b5f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_members_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_members_test.h
@@ -15,9 +15,13 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_
+#include <cstddef>
+#include <memory>
#include <type_traits>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h
index 1d686afb21d..e9b3a771435 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h
@@ -15,10 +15,13 @@
#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_
+#include <cstddef>
#include <type_traits>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/hash_policy_testing.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_test.cc
index a134b53984b..ef99624d276 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/unordered_set_test.cc
@@ -12,8 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <string>
#include <unordered_set>
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/container/internal/hash_policy_testing.h"
#include "absl/container/internal/unordered_set_constructor_test.h"
#include "absl/container/internal/unordered_set_lookup_test.h"
#include "absl/container/internal/unordered_set_members_test.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map_test.cc
index 8b95c123eee..a905e920c4c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map_test.cc
@@ -19,6 +19,7 @@
#include <cstdint>
#include <functional>
#include <memory>
+#include <stdexcept>
#include <string>
#include <tuple>
#include <type_traits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map.h b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map.h
index 75fc0ccab6c..4a65ef55938 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map.h
@@ -45,6 +45,7 @@
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/node_slot_policy.h"
@@ -681,11 +682,11 @@ class NodeHashMapPolicy
static Value& value(value_type* elem) { return elem->second; }
static const Value& value(const value_type* elem) { return elem->second; }
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return memory_internal::IsLayoutCompatible<Key, Value>::value
? &TypeErasedDerefAndApplyToSlotFirstFn<Hash, value_type,
- kIsDefault, kSeedShift>
+ kIsAbsl, kSeedShift>
: nullptr;
}
};
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_set.h b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_set.h
index 9da52e7c64c..726502987f4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_set.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_set.h
@@ -43,6 +43,7 @@
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/node_slot_policy.h"
@@ -582,9 +583,9 @@ struct NodeHashSetPolicy
static size_t element_space_used(const T*) { return sizeof(T); }
- template <class Hash, bool kIsDefault, size_t kSeedShift>
+ template <class Hash, bool kIsAbsl, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedDerefAndApplyToSlotFn<Hash, T, kIsDefault, kSeedShift>;
+ return &TypeErasedDerefAndApplyToSlotFn<Hash, T, kIsAbsl, kSeedShift>;
}
};
} // namespace container_internal
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/sample_element_size_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/sample_element_size_test.cc
index 9ce19fe4f7f..0507aa10d6b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/sample_element_size_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/sample_element_size_test.cc
@@ -13,12 +13,14 @@
// limitations under the License.
#include <cstddef>
+#include <cstring>
#include <unordered_set>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/container/internal/hashtablez_sampler.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.bazel
index 88b9ea26680..10b5a5f5399 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.bazel
@@ -84,8 +84,8 @@ cc_library(
"//absl/base:cpu_detect",
"//absl/base:endian",
"//absl/base:prefetch",
- "//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
],
)
@@ -99,6 +99,7 @@ cc_test(
":crc32c",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -146,6 +147,7 @@ cc_test(
"//absl/random",
"//absl/random:distributions",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -206,7 +208,7 @@ cc_binary(
deps = [
":crc32c",
"//absl/memory",
- "//absl/strings",
+ "//absl/strings:string_view",
"@google_benchmark//:benchmark_main",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn
index fdc709273a0..f0c8e74715f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn
@@ -50,10 +50,10 @@ absl_source_set("crc32c") {
"//third_party/abseil-cpp/absl/base:cpu_detect",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:prefetch",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/strings:string_view",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("crc32c_test") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/crc/CMakeLists.txt
index 28f0bab3c6f..42693962652 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/CMakeLists.txt
@@ -53,14 +53,14 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::base_cpu_detect
- absl::crc_internal
- absl::non_temporal_memcpy
absl::config
absl::core_headers
+ absl::crc_internal
absl::endian
+ absl::non_temporal_memcpy
absl::prefetch
absl::str_format
- absl::strings
+ absl::string_view
)
absl_cc_test(
@@ -72,8 +72,9 @@ absl_cc_test(
${ABSL_DEFAULT_COPTS}
DEPS
absl::crc32c
- absl::strings
absl::str_format
+ absl::string_view
+ absl::strings
GTest::gtest_main
)
@@ -98,9 +99,9 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::non_temporal_arm_intrinsics
absl::config
absl::core_headers
+ absl::non_temporal_arm_intrinsics
)
absl_cc_test(
@@ -113,8 +114,9 @@ absl_cc_test(
DEPS
absl::crc32c
absl::memory
- absl::random_random
absl::random_distributions
+ absl::random_random
+ absl::string_view
absl::strings
GTest::gtest_main
)
@@ -141,10 +143,10 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::crc32c
absl::config
- absl::strings
+ absl::crc32c
absl::no_destructor
+ absl::strings
)
absl_cc_test(
@@ -155,7 +157,7 @@ absl_cc_test(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::crc_cord_state
absl::crc32c
+ absl::crc_cord_state
GTest::gtest_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc
index 902056373c4..ed826e21e0f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc
@@ -17,6 +17,7 @@
#include <cstddef>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/crc/internal/crc.h"
#include "absl/crc/internal/crc32c.h"
#include "absl/crc/internal/crc_memcpy.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h
index 4ce941dc440..edeacd059e1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h
@@ -29,6 +29,7 @@
#include <cstdint>
#include <ostream>
+#include "absl/base/config.h"
#include "absl/crc/internal/crc32c_inline.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.cc b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.cc
index ec6a031c512..d135e3c87be 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.cc
@@ -45,6 +45,7 @@
#include <cstdint>
#include <iterator>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/prefetch.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_internal.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_internal.h
index ac9c38d68d8..f4d128adf10 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_internal.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_internal.h
@@ -20,6 +20,7 @@
#include <memory>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/optimization.h"
#include "absl/crc/internal/crc.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel
index d3eb74da5ae..b36967a399c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel
@@ -115,6 +115,7 @@ cc_library(
"//absl/base:malloc_internal",
"//absl/base:raw_logging_internal",
"//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -144,6 +145,7 @@ cc_test(
"//absl/memory",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"@googletest//:gtest",
],
)
@@ -446,6 +448,7 @@ cc_test(
tags = ["notsan"],
deps = [
":stack_consumption",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/log",
"@googletest//:gtest",
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn
index 8d621a847ac..e136a4ccf7b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn
@@ -252,6 +252,7 @@ absl_test("stack_consumption_test") {
sources = [ "internal/stack_consumption_test.cc" ]
deps = [
":stack_consumption",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/log",
]
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
index fbdb550f832..247e82f2973 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/CMakeLists.txt
@@ -38,9 +38,9 @@ absl_cc_library(
LINKOPTS
$<$<BOOL:${EXECINFO_LIBRARY}>:${EXECINFO_LIBRARY}>
DEPS
- absl::debugging_internal
absl::config
absl::core_headers
+ absl::debugging_internal
absl::dynamic_annotations
absl::malloc_internal
absl::raw_logging_internal
@@ -55,11 +55,11 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::stacktrace
absl::config
absl::core_headers
absl::errno_saver
absl::span
+ absl::stacktrace
GTest::gmock_main
)
@@ -82,14 +82,15 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
$<$<BOOL:${MINGW}>:-ldbghelp>
DEPS
- absl::debugging_internal
- absl::demangle_internal
absl::base
absl::config
absl::core_headers
+ absl::debugging_internal
+ absl::demangle_internal
absl::dynamic_annotations
absl::malloc_internal
absl::raw_logging_internal
+ absl::string_view
absl::strings
PUBLIC
)
@@ -114,8 +115,8 @@ absl_cc_test(
absl::malloc_internal
absl::memory
absl::stack_consumption
- absl::strings
absl::str_format
+ absl::string_view
absl::symbolize
GTest::gmock
)
@@ -131,11 +132,11 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::stacktrace
- absl::symbolize
absl::config
absl::core_headers
absl::raw_logging_internal
+ absl::stacktrace
+ absl::symbolize
)
absl_cc_library(
@@ -148,12 +149,12 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::examine_stack
- absl::stacktrace
absl::base
absl::config
absl::core_headers
+ absl::examine_stack
absl::raw_logging_internal
+ absl::stacktrace
PUBLIC
)
@@ -167,10 +168,10 @@ absl_cc_test(
DEPS
absl::check
absl::failure_signal_handler
+ absl::raw_logging_internal
absl::stacktrace
- absl::symbolize
absl::strings
- absl::raw_logging_internal
+ absl::symbolize
Threads::Threads
GTest::gmock
)
@@ -191,8 +192,8 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::core_headers
absl::config
+ absl::core_headers
absl::dynamic_annotations
absl::errno_saver
absl::raw_logging_internal
@@ -222,12 +223,12 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::demangle_internal
- absl::stack_consumption
absl::config
absl::core_headers
+ absl::demangle_internal
absl::log
absl::memory
+ absl::stack_consumption
GTest::gmock_main
)
@@ -282,8 +283,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::decode_rust_punycode
absl::config
+ absl::decode_rust_punycode
GTest::gmock_main
)
@@ -311,8 +312,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::demangle_rust
absl::config
+ absl::demangle_rust
GTest::gmock_main
)
@@ -338,8 +339,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::utf8_for_code_point
absl::config
+ absl::utf8_for_code_point
GTest::gmock_main
)
@@ -368,8 +369,8 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::leak_check
absl::base
+ absl::leak_check
absl::log
GTest::gmock_main
)
@@ -399,9 +400,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::stack_consumption
absl::core_headers
absl::log
+ absl::stack_consumption
GTest::gmock_main
)
@@ -412,7 +413,7 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::stacktrace
absl::leak_check
+ absl::stacktrace
PUBLIC
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc
index e15d49de599..6d98d39e50c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc
@@ -219,7 +219,7 @@ static bool SetupAlternateStackOnce() {
// if the system supports using an alternate stack.
static int MaybeSetupAlternateStack() {
#ifdef ABSL_HAVE_SIGALTSTACK
- ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce();
+ [[maybe_unused]] static const bool kOnce = SetupAlternateStackOnce();
return SA_ONSTACK;
#else
return 0;
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc
index e9be2caf5a7..88aa5164d99 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc
@@ -19,6 +19,8 @@
#include <cerrno>
+#include "absl/base/config.h"
+
#if !defined(__linux__) || defined(__ANDROID__)
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc
index b54a1b28c01..a46adf19be9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption.cc
@@ -15,6 +15,8 @@
#include "absl/debugging/internal/stack_consumption.h"
+#include "absl/base/config.h"
+
#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION
#include <signal.h>
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
index 0255ac8f36c..ee93f013d7b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stack_consumption_test.cc
@@ -15,6 +15,8 @@
#include "absl/debugging/internal/stack_consumption.h"
+#include "absl/base/config.h"
+
#ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION
#include <string.h>
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc
index f23c29cb0a0..a20a71585ab 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc
@@ -51,11 +51,10 @@ static inline void **StacktracePowerPCGetLRPtr(void **sp) {
return (sp + 2);
#elif defined(_CALL_SYSV)
return (sp + 1);
-#elif defined(__APPLE__) || defined(__FreeBSD__) || \
- (defined(__linux__) && defined(__PPC64__))
+#elif defined(__APPLE__) || defined(__PPC64__)
// This check is in case the compiler doesn't define _CALL_AIX/etc.
return (sp + 2);
-#elif defined(__linux)
+#elif defined(__linux__) || defined(__FreeBSD__)
// This check is in case the compiler doesn't define _CALL_SYSV.
return (sp + 1);
#else
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc
index 9d96f3bc87e..48d4f505b61 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc
@@ -21,6 +21,7 @@
#include <atomic>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/debugging/internal/elf_mem_image.h"
#ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h
index 6562c6c2350..86612616466 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h
@@ -42,6 +42,7 @@
#include <atomic>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/debugging/internal/elf_mem_image.h"
#ifdef ABSL_HAVE_ELF_MEM_IMAGE
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/stacktrace_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/stacktrace_test.cc
index 0bf94f70d57..02950bcedad 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/stacktrace_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/stacktrace_test.cc
@@ -68,7 +68,7 @@ struct StackTrace {
// This test is currently only known to pass on Linux x86_64/aarch64.
#if defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__))
ABSL_ATTRIBUTE_NOINLINE void Unwind(void* p) {
- ABSL_ATTRIBUTE_UNUSED static void* volatile sink = p;
+ [[maybe_unused]] static void* volatile sink = p;
constexpr int kSize = 16;
void* stack[kSize];
int frames[kSize];
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize.h b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize.h
index 43d93a86822..07133e027b3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize.h
@@ -52,6 +52,7 @@
#ifndef ABSL_DEBUGGING_SYMBOLIZE_H_
#define ABSL_DEBUGGING_SYMBOLIZE_H_
+#include "absl/base/config.h"
#include "absl/debugging/internal/symbolize.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
index 06c56344543..182d0fd19a9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
@@ -1104,8 +1104,8 @@ static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap(
LineReader reader(wrapped_maps_fd.get(), static_cast<char *>(tmp_buf),
tmp_buf_size);
while (true) {
- const char *cursor;
- const char *eol;
+ const char *cursor = nullptr;
+ const char *eol = nullptr;
if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line.
break;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.bazel
index 4dd3b33fa32..59cae9978a0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.bazel
@@ -48,7 +48,7 @@ cc_library(
],
deps = [
"//absl/base:config",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -72,7 +72,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:no_destructor",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -96,6 +96,7 @@ cc_library(
"//absl/base:core_headers",
"//absl/base:no_destructor",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -118,6 +119,7 @@ cc_library(
"//absl/numeric:int128",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:optional",
],
)
@@ -157,7 +159,7 @@ cc_library(
"//absl/base:config",
"//absl/base:fast_type_id",
"//absl/base:nullability",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:optional",
],
)
@@ -181,7 +183,7 @@ cc_library(
":commandlineflag",
":commandlineflag_internal",
"//absl/base:config",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -208,6 +210,7 @@ cc_library(
"//absl/base:no_destructor",
"//absl/container:flat_hash_map",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -239,6 +242,7 @@ cc_library(
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
"//absl/utility",
],
@@ -261,7 +265,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:nullability",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -292,6 +296,7 @@ cc_library(
"//absl/base:core_headers",
"//absl/base:no_destructor",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -312,7 +317,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -343,6 +348,7 @@ cc_library(
"//absl/base:core_headers",
"//absl/base:no_destructor",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
@@ -373,6 +379,7 @@ cc_test(
":reflection",
"//absl/memory",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -421,6 +428,7 @@ cc_test(
"//absl/base:raw_logging_internal",
"//absl/numeric:int128",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -445,7 +453,7 @@ cc_binary(
":marshalling",
":parse",
":reflection",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"@google_benchmark//:benchmark_main",
],
@@ -461,6 +469,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":marshalling",
+ "//absl/numeric:int128",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -491,6 +500,7 @@ cc_test(
"//absl/base:scoped_set_env",
"//absl/log",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -527,6 +537,7 @@ cc_test(
deps = [
":program_name",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -553,6 +564,8 @@ cc_test(
":reflection",
"//absl/memory",
"//absl/strings",
+ "//absl/strings:string_view",
+ "//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -592,6 +605,7 @@ cc_test(
":path_util",
":program_name",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -622,6 +636,7 @@ cc_test(
":usage",
":usage_internal",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn
index ffba58ed66a..fd9ab729cd1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn
@@ -11,7 +11,6 @@ absl_source_set("path_util") {
visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -28,7 +27,6 @@ absl_source_set("program_name") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:no_destructor",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
]
@@ -93,7 +91,6 @@ absl_source_set("commandlineflag") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
"//third_party/abseil-cpp/absl/base:nullability",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -110,7 +107,6 @@ absl_source_set("private_handle_accessor") {
":commandlineflag",
":commandlineflag_internal",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -181,7 +177,6 @@ absl_source_set("flag") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:nullability",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -216,7 +211,6 @@ absl_source_set("usage") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
]
@@ -281,7 +275,10 @@ absl_test("flag_test") {
absl_test("marshalling_test") {
sources = [ "marshalling_test.cc" ]
- deps = [ ":marshalling" ]
+ deps = [
+ ":marshalling",
+ "//third_party/abseil-cpp/absl/numeric:int128",
+ ]
}
absl_test("parse_test") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/flags/CMakeLists.txt
index 0c75c93dee8..a96e294cb30 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/CMakeLists.txt
@@ -26,7 +26,7 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::strings
+ absl::string_view
PUBLIC
)
@@ -34,10 +34,10 @@ absl_cc_library(
absl_cc_library(
NAME
flags_program_name
- SRCS
- "internal/program_name.cc"
HDRS
"internal/program_name.h"
+ SRCS
+ "internal/program_name.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -45,9 +45,9 @@ absl_cc_library(
DEPS
absl::config
absl::core_headers
- absl::no_destructor
absl::flags_path_util
- absl::strings
+ absl::no_destructor
+ absl::string_view
absl::synchronization
PUBLIC
)
@@ -55,10 +55,10 @@ absl_cc_library(
absl_cc_library(
NAME
flags_config
- SRCS
- "usage_config.cc"
HDRS
"config.h"
+ SRCS
+ "usage_config.cc"
"usage_config.h"
COPTS
${ABSL_DEFAULT_COPTS}
@@ -66,10 +66,11 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
+ absl::core_headers
absl::flags_path_util
absl::flags_program_name
- absl::core_headers
absl::no_destructor
+ absl::string_view
absl::strings
absl::synchronization
)
@@ -77,10 +78,10 @@ absl_cc_library(
absl_cc_library(
NAME
flags_marshalling
- SRCS
- "marshalling.cc"
HDRS
"marshalling.h"
+ SRCS
+ "marshalling.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -88,21 +89,22 @@ absl_cc_library(
DEPS
absl::config
absl::core_headers
- absl::log_severity
absl::int128
+ absl::log_severity
absl::optional
- absl::strings
absl::str_format
+ absl::string_view
+ absl::strings
)
# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
flags_commandlineflag_internal
- SRCS
- "internal/commandlineflag.cc"
HDRS
"internal/commandlineflag.h"
+ SRCS
+ "internal/commandlineflag.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -116,10 +118,10 @@ absl_cc_library(
absl_cc_library(
NAME
flags_commandlineflag
- SRCS
- "commandlineflag.cc"
HDRS
"commandlineflag.h"
+ SRCS
+ "commandlineflag.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -130,17 +132,17 @@ absl_cc_library(
absl::flags_commandlineflag_internal
absl::nullability
absl::optional
- absl::strings
+ absl::string_view
)
# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
flags_private_handle_accessor
- SRCS
- "internal/private_handle_accessor.cc"
HDRS
"internal/private_handle_accessor.h"
+ SRCS
+ "internal/private_handle_accessor.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -149,16 +151,16 @@ absl_cc_library(
absl::config
absl::flags_commandlineflag
absl::flags_commandlineflag_internal
- absl::strings
+ absl::string_view
)
absl_cc_library(
NAME
flags_reflection
- SRCS
- "reflection.cc"
HDRS
"reflection.h"
+ SRCS
+ "reflection.cc"
"internal/registry.h"
COPTS
${ABSL_DEFAULT_COPTS}
@@ -168,22 +170,23 @@ absl_cc_library(
absl::config
absl::fast_type_id
absl::flags_commandlineflag
- absl::flags_private_handle_accessor
absl::flags_config
- absl::strings
- absl::synchronization
+ absl::flags_private_handle_accessor
absl::flat_hash_map
absl::no_destructor
+ absl::string_view
+ absl::strings
+ absl::synchronization
)
# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
flags_internal
- SRCS
- "internal/flag.cc"
HDRS
"internal/flag.h"
+ SRCS
+ "internal/flag.cc"
"internal/sequence_lock.h"
COPTS
${ABSL_DEFAULT_COPTS}
@@ -197,9 +200,9 @@ absl_cc_library(
absl::flags_commandlineflag_internal
absl::flags_config
absl::flags_marshalling
+ absl::meta
absl::no_destructor
absl::synchronization
- absl::meta
absl::utility
PUBLIC
)
@@ -216,11 +219,11 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
+ absl::core_headers
absl::flags_commandlineflag
absl::flags_config
absl::flags_internal
absl::flags_reflection
- absl::core_headers
absl::nullability
absl::strings
)
@@ -229,24 +232,25 @@ absl_cc_library(
absl_cc_library(
NAME
flags_usage_internal
- SRCS
- "internal/usage.cc"
HDRS
"internal/usage.h"
+ SRCS
+ "internal/usage.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::flags_config
absl::flags
absl::flags_commandlineflag
+ absl::flags_config
absl::flags_internal
absl::flags_path_util
absl::flags_private_handle_accessor
absl::flags_program_name
absl::flags_reflection
+ absl::string_view
absl::strings
absl::synchronization
)
@@ -254,10 +258,10 @@ absl_cc_library(
absl_cc_library(
NAME
flags_usage
- SRCS
- "usage.cc"
HDRS
"usage.h"
+ SRCS
+ "usage.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -268,17 +272,17 @@ absl_cc_library(
absl::flags_usage_internal
absl::no_destructor
absl::raw_logging_internal
- absl::strings
+ absl::string_view
absl::synchronization
)
absl_cc_library(
NAME
flags_parse
- SRCS
- "parse.cc"
HDRS
"internal/parse.h"
+ SRCS
+ "parse.cc"
"parse.h"
COPTS
${ABSL_DEFAULT_COPTS}
@@ -288,16 +292,17 @@ absl_cc_library(
absl::algorithm_container
absl::config
absl::core_headers
- absl::flags_config
absl::flags
absl::flags_commandlineflag
absl::flags_commandlineflag_internal
+ absl::flags_config
absl::flags_internal
absl::flags_private_handle_accessor
absl::flags_program_name
absl::flags_reflection
absl::flags_usage
absl::no_destructor
+ absl::string_view
absl::strings
absl::synchronization
)
@@ -319,6 +324,7 @@ absl_cc_test(
absl::flags_private_handle_accessor
absl::flags_reflection
absl::memory
+ absl::string_view
absl::strings
GTest::gtest_main
)
@@ -353,6 +359,7 @@ absl_cc_test(
absl::flags_reflection
absl::int128
absl::raw_logging_internal
+ absl::string_view
absl::strings
absl::time
GTest::gtest_main
@@ -386,6 +393,7 @@ absl_cc_test(
absl::log
absl::scoped_set_env
absl::span
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -411,6 +419,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::flags_program_name
+ absl::string_view
absl::strings
GTest::gtest_main
)
@@ -428,6 +437,7 @@ absl_cc_test(
absl::flags_reflection
absl::flags_usage
absl::memory
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -457,6 +467,7 @@ absl_cc_test(
absl::flags_config
absl::flags_path_util
absl::flags_program_name
+ absl::string_view
absl::strings
GTest::gtest_main
)
@@ -469,13 +480,14 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::flags_config
absl::flags
+ absl::flags_config
+ absl::flags_parse
absl::flags_path_util
absl::flags_program_name
- absl::flags_parse
absl::flags_reflection
absl::flags_usage
+ absl::string_view
absl::strings
GTest::gmock
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/config_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/config_test.cc
index 5c74d765f24..00e9b666c3e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/config_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/config_test.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include "absl/flags/config.h"
+
#include "gtest/gtest.h"
#ifdef __APPLE__
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/flag.h b/deps/v8/third_party/abseil-cpp/absl/flags/flag.h
index 4c328e38c90..2a950491c05 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/flag.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/flag.h
@@ -300,7 +300,7 @@ ABSL_NAMESPACE_END
// retired flags are cleaned up.
#define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \
static absl::flags_internal::RetiredFlag<type> RETIRED_FLAGS_##name; \
- ABSL_ATTRIBUTE_UNUSED static const auto RETIRED_FLAGS_REG_##name = \
+ [[maybe_unused]] static const auto RETIRED_FLAGS_REG_##name = \
(RETIRED_FLAGS_##name.Retire(#name), \
::absl::flags_internal::FlagRegistrarEmpty{})
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/flag_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
index bbe9cbae490..be435d92e7f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
@@ -15,6 +15,7 @@
#include <stdint.h>
+#include <cstddef>
#include <optional>
#include <string>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/flag_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/flag_test.cc
index 1dd2f5c97be..7cbce8876bc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/flag_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/flag_test.cc
@@ -937,7 +937,7 @@ ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
namespace {
-bool initialization_order_fiasco_test ABSL_ATTRIBUTE_UNUSED = [] {
+bool initialization_order_fiasco_test [[maybe_unused]] = [] {
// Iterate over all the flags during static initialization.
// This should not trigger ASan's initialization-order-fiasco.
auto* handle1 = absl::FindCommandLineFlag("flag_on_separate_file");
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/commandlineflag.cc b/deps/v8/third_party/abseil-cpp/absl/flags/internal/commandlineflag.cc
index 3c114d1017d..4ba8a8e450f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/commandlineflag.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/commandlineflag.cc
@@ -15,6 +15,8 @@
#include "absl/flags/internal/commandlineflag.h"
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace flags_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/flag.h b/deps/v8/third_party/abseil-cpp/absl/flags/internal/flag.h
index 7855a104b45..8ef95ab9788 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/flag.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/flag.h
@@ -25,6 +25,7 @@
#include <string>
#include <type_traits>
#include <typeinfo>
+#include <utility>
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
@@ -43,7 +44,7 @@
#include "absl/synchronization/mutex.h"
#include "absl/utility/utility.h"
-namespace absl {
+ namespace absl {
ABSL_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
@@ -605,8 +606,8 @@ class FlagImpl final : public CommandLineFlag {
}
template <typename T,
std::enable_if_t<flags_internal::StorageKind<T>() ==
- FlagValueStorageKind::kOneWordAtomic,
- int> = 0>
+ FlagValueStorageKind::kOneWordAtomic,
+ int> = 0>
void Read(T* value) const ABSL_LOCKS_EXCLUDED(DataGuard()) {
int64_t v = ReadOneWord();
std::memcpy(value, static_cast<const void*>(&v), sizeof(T));
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/registry.h b/deps/v8/third_party/abseil-cpp/absl/flags/internal/registry.h
index be9aaccc7ef..a1f4a827644 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/registry.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/registry.h
@@ -16,6 +16,7 @@
#ifndef ABSL_FLAGS_INTERNAL_REGISTRY_H_
#define ABSL_FLAGS_INTERNAL_REGISTRY_H_
+#include <cstddef>
#include <functional>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock.h b/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock.h
index 36318ab9d36..da04ff48569 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock.h
@@ -23,6 +23,7 @@
#include <cassert>
#include <cstring>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock_test.cc
index a244d67d18b..79b301f54d1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/sequence_lock_test.cc
@@ -15,6 +15,7 @@
#include <algorithm>
#include <atomic>
+#include <cstdint>
#include <thread> // NOLINT(build/c++11)
#include <tuple>
#include <vector>
@@ -23,6 +24,7 @@
#include "absl/base/internal/sysinfo.h"
#include "absl/container/fixed_array.h"
#include "absl/time/clock.h"
+#include "absl/time/time.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/marshalling_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/marshalling_test.cc
index a5faabca06e..9629744ec0a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/marshalling_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/marshalling_test.cc
@@ -24,6 +24,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/numeric/int128.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/parse.h b/deps/v8/third_party/abseil-cpp/absl/flags/parse.h
index fdb3d1eb89d..b1a41098f5f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/parse.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/parse.h
@@ -28,6 +28,7 @@
#include "absl/base/config.h"
#include "absl/flags/internal/parse.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc b/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc
index e92ff961b45..0729ba0a2e8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc
@@ -17,9 +17,14 @@
#include <assert.h>
+#include <algorithm>
#include <atomic>
+#include <cstdlib>
+#include <functional>
+#include <memory>
#include <string>
#include <utility>
+#include <vector>
#include "absl/base/config.h"
#include "absl/base/no_destructor.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/reflection.h b/deps/v8/third_party/abseil-cpp/absl/flags/reflection.h
index e6baf5de4b0..54b3e9aef9c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/reflection.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/reflection.h
@@ -29,6 +29,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/flags/commandlineflag.h"
#include "absl/flags/internal/commandlineflag.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/reflection_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/reflection_test.cc
index 996a458fa79..99a3525d83f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/reflection_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/reflection_test.cc
@@ -15,16 +15,21 @@
#include "absl/flags/reflection.h"
+#include <cstdint>
#include <memory>
#include <string>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/flags/config.h"
#include "absl/flags/flag.h"
#include "absl/memory/memory.h"
+#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
ABSL_FLAG(int, int_flag, 1, "int_flag help");
ABSL_FLAG(std::string, string_flag, "dflt", "string_flag help");
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/usage.cc b/deps/v8/third_party/abseil-cpp/absl/flags/usage.cc
index e42b4540228..46e7524bf3b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/usage.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/usage.cc
@@ -16,6 +16,7 @@
#include <stdlib.h>
+#include <cstdlib>
#include <string>
#include "absl/base/attributes.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.bazel
index c41b211c889..d1b46c79b1e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.bazel
@@ -110,6 +110,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:public"],
deps = [
+ "//absl/base:config",
"//absl/container:compressed_tuple",
"//absl/meta:type_traits",
"//absl/utility",
@@ -201,6 +202,7 @@ cc_binary(
deps = [
":any_invocable",
":function_ref",
+ "//absl/base:config",
"//absl/base:core_headers",
"@google_benchmark//:benchmark_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn
index 585574a0cf7..3b592b5a66c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn
@@ -16,6 +16,7 @@ absl_source_set("any_invocable") {
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("any_invocable_test") {
@@ -45,6 +46,7 @@ absl_source_set("bind_back") {
"//third_party/abseil-cpp/absl/container:compressed_tuple",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("bind_back_test") {
@@ -59,10 +61,12 @@ absl_source_set("bind_front") {
sources = [ "internal/front_binder.h" ]
public = [ "bind_front.h" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/container:compressed_tuple",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("bind_front_test") {
@@ -83,6 +87,7 @@ absl_source_set("function_ref") {
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("function_ref_test") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/functional/CMakeLists.txt
index 77801749c0d..1ddfa291b1c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/CMakeLists.txt
@@ -17,10 +17,10 @@
absl_cc_library(
NAME
any_invocable
- SRCS
- "internal/any_invocable.h"
HDRS
"any_invocable.h"
+ SRCS
+ "internal/any_invocable.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -56,10 +56,10 @@ absl_cc_test(
absl_cc_library(
NAME
bind_back
- SRCS
- "internal/back_binder.h"
HDRS
"bind_back.h"
+ SRCS
+ "internal/back_binder.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -85,10 +85,10 @@ absl_cc_test(
absl_cc_library(
NAME
bind_front
- SRCS
- "internal/front_binder.h"
HDRS
"bind_front.h"
+ SRCS
+ "internal/front_binder.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -112,16 +112,16 @@ absl_cc_test(
absl_cc_library(
NAME
function_ref
- SRCS
- "internal/function_ref.h"
HDRS
"function_ref.h"
+ SRCS
+ "internal/function_ref.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::any_invocable
absl::config
absl::core_headers
- absl::any_invocable
absl::meta
absl::utility
PUBLIC
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test.h b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test.h
index d667fa427ec..6d09c125268 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test.h
@@ -24,8 +24,6 @@
#ifndef ABSL_FUNCTIONAL_ANY_INVOCABLE_TEST_H_
#define ABSL_FUNCTIONAL_ANY_INVOCABLE_TEST_H_
-#include "absl/functional/any_invocable.h"
-
#include <cstddef>
#include <cstdlib>
#include <functional>
@@ -34,10 +32,12 @@
#include <memory>
#include <numeric>
#include <type_traits>
+#include <utility>
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/base/nullability.h"
+#include "absl/functional/any_invocable.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst1.cc b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst1.cc
index 68a5955fa48..2bc95d44f6d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst1.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst1.cc
@@ -18,6 +18,7 @@
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+#include "gtest/gtest.h"
#include "absl/functional/any_invocable_test.h"
namespace absl_any_invocable_test {
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst2.cc b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst2.cc
index 5b5f22a25d3..6e014026a50 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst2.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst2.cc
@@ -18,6 +18,7 @@
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+#include "gtest/gtest.h"
#include "absl/functional/any_invocable_test.h"
namespace absl_any_invocable_test {
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst3.cc b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst3.cc
index ba23e6391dc..8d492b335e4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst3.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst3.cc
@@ -18,6 +18,7 @@
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+#include "gtest/gtest.h"
#include "absl/functional/any_invocable_test.h"
namespace absl_any_invocable_test {
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst4.cc b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst4.cc
index 0549a1e1291..ac21ca9adf0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst4.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/any_invocable_test_inst4.cc
@@ -18,6 +18,7 @@
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+#include "gtest/gtest.h"
#include "absl/functional/any_invocable_test.h"
namespace absl_any_invocable_test {
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/bind_front.h b/deps/v8/third_party/abseil-cpp/absl/functional/bind_front.h
index 4dcee393f02..45ca4fc45da 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/bind_front.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/bind_front.h
@@ -30,6 +30,7 @@
#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
#define ABSL_FUNCTIONAL_BIND_FRONT_H_
+#include "absl/base/config.h"
#if __has_include(<version>)
#include <version>
#endif
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/bind_front_test.cc b/deps/v8/third_party/abseil-cpp/absl/functional/bind_front_test.cc
index a759dbe775c..6e87d43c422 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/bind_front_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/bind_front_test.cc
@@ -19,6 +19,7 @@
#include <functional>
#include <memory>
#include <string>
+#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -165,9 +166,7 @@ TEST(BindTest, StoreByPointer) {
EXPECT_EQ(&s.value, &g());
}
-int Sink(std::unique_ptr<int> p) {
- return *p;
-}
+int Sink(std::unique_ptr<int> p) { return *p; }
std::unique_ptr<int> Factory(int n) { return std::make_unique<int>(n); }
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/function_ref_test.cc b/deps/v8/third_party/abseil-cpp/absl/functional/function_ref_test.cc
index 69513f42148..a54865fbc39 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/function_ref_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/function_ref_test.cc
@@ -14,6 +14,7 @@
#include "absl/functional/function_ref.h"
+#include <atomic>
#include <functional>
#include <memory>
#include <type_traits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/function_type_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/functional/function_type_benchmark.cc
index 513233b46b0..e4ba3a5ed1e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/function_type_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/function_type_benchmark.cc
@@ -17,6 +17,7 @@
#include <string>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/functional/any_invocable.h"
#include "absl/functional/function_ref.h"
#include "benchmark/benchmark.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/internal/front_binder.h b/deps/v8/third_party/abseil-cpp/absl/functional/internal/front_binder.h
index d0c3a5a0506..fcada9ceca0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/internal/front_binder.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/internal/front_binder.h
@@ -21,6 +21,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/container/internal/compressed_tuple.h"
#include "absl/meta/type_traits.h"
#include "absl/utility/utility.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/internal/function_ref.h b/deps/v8/third_party/abseil-cpp/absl/functional/internal/function_ref.h
index 1e905fa2571..a6b3794f1b4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/internal/function_ref.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/internal/function_ref.h
@@ -19,6 +19,7 @@
#include <functional>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/functional/any_invocable.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel
index 41d7d686b0c..5fae4e2a272 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel
@@ -57,7 +57,7 @@ cc_library(
"//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/numeric:int128",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:optional",
"//absl/types:variant",
"//absl/utility",
@@ -72,6 +72,7 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":spy_hash_state",
+ "//absl/base:config",
"//absl/meta:type_traits",
"//absl/strings",
"//absl/types:variant",
@@ -141,9 +142,9 @@ cc_binary(
"//absl/base:core_headers",
"//absl/container:flat_hash_set",
"//absl/random",
- "//absl/strings",
"//absl/strings:cord",
"//absl/strings:cord_test_helpers",
+ "//absl/strings:string_view",
"@google_benchmark//:benchmark_main",
],
)
@@ -158,6 +159,7 @@ cc_library(
deps = [
":hash",
":weakly_mixed_integer",
+ "//absl/base:config",
"//absl/strings",
"//absl/strings:str_format",
],
@@ -189,6 +191,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":city",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -218,6 +221,7 @@ cc_test(
deps = [
":hash",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn
index f4aba2abdba..02ddb5370fd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn
@@ -24,12 +24,12 @@ absl_source_set("hash") {
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_source_set("hash_testing") {
@@ -37,6 +37,7 @@ absl_source_set("hash_testing") {
public = [ "hash_testing.h" ]
deps = [
":spy_hash_state",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:variant",
@@ -90,6 +91,7 @@ absl_source_set("spy_hash_state") {
deps = [
":hash",
":weakly_mixed_integer",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
]
@@ -109,7 +111,10 @@ absl_source_set("city") {
absl_test("city_test") {
sources = [ "internal/city_test.cc" ]
- deps = [ ":city" ]
+ deps = [
+ ":city",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
}
absl_source_set("weakly_mixed_integer") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/hash/CMakeLists.txt
index c593a5bc3c6..0c7e7f43b60 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/CMakeLists.txt
@@ -32,12 +32,12 @@ absl_cc_library(
absl::endian
absl::fixed_array
absl::function_ref
- absl::meta
absl::int128
- absl::strings
+ absl::meta
absl::optional
- absl::variant
+ absl::string_view
absl::utility
+ absl::variant
absl::weakly_mixed_integer
PUBLIC
)
@@ -50,8 +50,8 @@ absl_cc_library(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::spy_hash_state
absl::meta
+ absl::spy_hash_state
absl::strings
absl::variant
GTest::gmock
@@ -90,12 +90,12 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::hash
- absl::hash_testing
- absl::config
absl::btree
+ absl::config
absl::flat_hash_map
absl::flat_hash_set
+ absl::hash
+ absl::hash_testing
absl::node_hash_map
absl::node_hash_set
GTest::gmock_main
@@ -115,8 +115,8 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::hash
- absl::strings
absl::str_format
+ absl::strings
absl::weakly_mixed_integer
TESTONLY
PUBLIC
@@ -133,9 +133,9 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::bits
absl::config
absl::core_headers
- absl::bits
absl::endian
)
@@ -172,6 +172,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::hash
+ absl::string_view
absl::strings
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/hash.h b/deps/v8/third_party/abseil-cpp/absl/hash/hash.h
index 7a767713c9b..bfccf2774f6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/hash.h
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/hash.h
@@ -22,6 +22,8 @@
// * The `absl::Hash` functor, which is used to invoke the hasher within the
// Abseil hashing framework. `absl::Hash<T>` supports most basic types and
// a number of Abseil types out of the box.
+// * The `absl::TransparentHash` functor, which provides transparent hashing
+// for heterogeneous lookup across multiple types in associative containers.
// * `AbslHashValue`, an extension point that allows you to extend types to
// support Abseil hashing without requiring you to define a hashing
// algorithm.
@@ -255,6 +257,89 @@ ABSL_NAMESPACE_BEGIN
template <typename T>
using Hash = absl::hash_internal::Hash<T>;
+// TransparentHash
+//
+// `absl::TransparentHash<Ts...>` is a transparent hash functor that provides
+// heterogeneous hashing across multiple types `Ts...` for associative
+// containers such as `absl::flat_hash_set` and `absl::flat_hash_map`.
+//
+// It exposes `operator()(const T&)` overloads for each type `T` in `Ts...`,
+// delegating each call to `absl::Hash<T>{}(value)`. It also defines the nested
+// type alias `using is_transparent = void;`, signaling to containers that
+// heterogeneous lookup is supported.
+//
+// If any type in `Ts...` is not hashable within the `absl::Hash` framework,
+// `absl::TransparentHash` is poisoned (its call operators are disabled) in the
+// same manner as `absl::Hash`.
+//
+// Duplicates types are allowed in `Ts...`.
+//
+// Requirements:
+//
+// For heterogeneous lookup to be correct, equivalent values across different
+// types must produce identical hash values. That is, if `a == b`, then
+// `TransparentHash{}(a) == TransparentHash{}(b)` must hold. This is typically
+// satisfied when the `AbslHashValue()` implementations for each type combine
+// identical fields in the same order.
+//
+// Usage:
+//
+// `absl::TransparentHash` can be used in two ways:
+//
+// 1. As an explicit `Hash` template argument to a container:
+//
+// absl::flat_hash_set<Name, absl::TransparentHash<Name, NameView>,
+// NameEq> set;
+//
+// 2. As the nested `absl_container_hash` type alias within a user-defined key
+// type:
+//
+// struct Name {
+// ...
+// using absl_container_hash = absl::TransparentHash<Name, NameView>;
+// };
+//
+// When `absl_container_hash` is defined in the key type, Abseil hash
+// containers will automatically use it and enable heterogeneous lookup by
+// default (using `std::equal_to<void>` for equality if `absl_container_eq`
+// is not provided).
+//
+// Example:
+//
+// struct NameView {
+// absl::string_view first;
+// absl::string_view last;
+//
+// template <typename H>
+// friend H AbslHashValue(H h, const NameView& nv) {
+// return H::combine(std::move(h), nv.first, nv.last);
+// }
+// friend bool operator==(const NameView& a, const NameView& b);
+// };
+//
+// struct Name {
+// std::string first;
+// std::string last;
+//
+// template <typename H>
+// friend H AbslHashValue(H h, const Name& n) {
+// return H::combine(std::move(h), n.first, n.last);
+// }
+// friend bool operator==(const Name& a, const Name& b);
+// friend bool operator==(const Name& a, const NameView& b);
+//
+// using absl_container_hash = absl::TransparentHash<Name, NameView>;
+// };
+//
+// absl::flat_hash_set<Name> names;
+// names.insert(Name{"John", "Doe"});
+//
+// // Look up using `NameView` without constructing a temporary `Name` or
+// // allocating memory:
+// assert(names.contains(NameView{"John", "Doe"}));
+template <typename... Ts>
+using TransparentHash = absl::hash_internal::TransparentHash<Ts...>;
+
// HashOf
//
// absl::HashOf() is a helper that generates a hash from the values of its
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/hash_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
index 978b5bcfb63..a18d38f8c07 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/hash_benchmark.cc
@@ -342,7 +342,7 @@ namespace {
// measurements.
static constexpr size_t kEntropySize = 16 << 10;
static char entropy[kEntropySize + 1024];
-ABSL_ATTRIBUTE_UNUSED static const bool kInitialized = [] {
+[[maybe_unused]] static const bool kInitialized = [] {
absl::BitGen gen;
static_assert(sizeof(entropy) % sizeof(uint64_t) == 0);
for (int i = 0; i != sizeof(entropy); i += sizeof(uint64_t)) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/hash_test.cc b/deps/v8/third_party/abseil-cpp/absl/hash/hash_test.cc
index 4198102effc..2afa986303c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/hash_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/hash_test.cc
@@ -34,6 +34,7 @@
#include <tuple>
#include <type_traits>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>
@@ -46,8 +47,6 @@
#include "absl/hash/hash_testing.h"
#include "absl/hash/internal/hash_test.h"
#include "absl/hash/internal/spy_hash_state.h"
-#include "absl/memory/memory.h"
-#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/strings/cord.h"
#include "absl/strings/cord_test_helpers.h"
@@ -1306,6 +1305,10 @@ TEST(SwisstableCollisions, DoubleRange) {
TEST(SwisstableCollisions, LowEntropyStrings) {
constexpr char kMinChar = 0;
constexpr char kMaxChar = 64;
+ // Scale the probe limit inversely with Group::kWidth so the test asserts a
+ // consistent bound on the number of probed slots across architectures.
+ constexpr size_t kMaxProbes =
+ 64 * 16 / absl::container_internal::Group::kWidth;
// These sizes cover the different hashing cases.
for (size_t size : {8u, 16u, 32u, 64u, 128u}) {
for (size_t b = 0; b < size - 1; ++b) {
@@ -1321,7 +1324,7 @@ TEST(SwisstableCollisions, LowEntropyStrings) {
s[b + 1] = c2;
set.insert(s);
ASSERT_LT(HashtableDebugAccess<decltype(set)>::GetNumProbes(set, s),
- 64)
+ kMaxProbes)
<< "size: " << size << "; bit: " << b;
}
}
@@ -1348,4 +1351,153 @@ TEST(SwisstableCollisions, LowEntropyInts) {
}
}
+struct NameView {
+ absl::string_view name;
+ absl::string_view lang;
+
+ friend bool operator==(const NameView& lhs, const NameView& rhs) {
+ return lhs.name == rhs.name && lhs.lang == rhs.lang;
+ }
+
+ template <typename H>
+ friend H AbslHashValue(H h, const NameView& name) {
+ return H::combine(std::move(h), name.name, name.lang);
+ }
+};
+
+struct Name {
+ std::string name;
+ std::string lang;
+
+ friend bool operator==(const Name& lhs, const Name& rhs) {
+ return lhs.name == rhs.name && lhs.lang == rhs.lang;
+ }
+ friend bool operator==(const NameView& lhs, const Name& rhs) {
+ return lhs.name == rhs.name && lhs.lang == rhs.lang;
+ }
+ friend bool operator==(const Name& lhs, const NameView& rhs) {
+ return lhs.name == rhs.name && lhs.lang == rhs.lang;
+ }
+
+ template <typename H>
+ friend H AbslHashValue(H h, const Name& name) {
+ return H::combine(std::move(h), name.name, name.lang);
+ }
+
+ using absl_container_hash = absl::TransparentHash<NameView, Name>;
+};
+
+template <typename NameHash>
+class TransparentHashTest : public testing::Test {};
+
+using NameHashTypes =
+ testing::Types<absl::TransparentHash<Name, NameView>,
+ absl::TransparentHash<Name, Name, NameView>,
+ absl::TransparentHash<Name, NameView, Name>,
+ absl::TransparentHash<Name, NameView, Name, NameView>,
+ absl::TransparentHash<Name, NameView, Name, NameView, Name,
+ NameView, Name>>;
+TYPED_TEST_SUITE(TransparentHashTest, NameHashTypes);
+
+TYPED_TEST(TransparentHashTest, BasicUsage) {
+ using NameHash = TypeParam;
+ static_assert(std::is_same_v<typename NameHash::is_transparent, void>);
+
+ EXPECT_FALSE((std::is_convertible_v<NameHash, absl::Hash<Name>>));
+ EXPECT_FALSE((std::is_convertible_v<NameHash, absl::Hash<NameView>>));
+
+ EXPECT_EQ(NameHash{}(Name{"foo", "en"}), NameHash{}(NameView{"foo", "en"}));
+
+ EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+ std::make_tuple(Name{"foo", "en"}, NameView{"foo", "en"},
+ Name{"bar", "en"}, NameView{"bar", "en"},
+ Name{"foo", "de"}, NameView{"foo", "de"},
+ Name{"bar", "de"}, NameView{"bar", "de"})));
+
+ absl::flat_hash_set<Name, NameHash, std::equal_to<>> set;
+ set.insert(Name{"foo", "en"});
+ EXPECT_TRUE(set.contains(NameView{"foo", "en"}));
+ EXPECT_TRUE(set.contains(Name{"foo", "en"}));
+
+ std::unordered_set<Name, NameHash, std::equal_to<>> std_set;
+ std_set.insert(Name{"foo", "en"});
+ EXPECT_TRUE(std_set.find(Name{"foo", "en"}) != std_set.end());
+}
+
+TEST(HashTest, TransparentHashDefaultLookUp) {
+ absl::flat_hash_set<Name> set;
+ set.insert(Name{"foo", "en"});
+ EXPECT_TRUE(set.contains(NameView{"foo", "en"}));
+ EXPECT_TRUE(set.contains(Name{"foo", "en"}));
+}
+
+struct MyString {
+ std::string s;
+
+ MyString() = default;
+ explicit MyString(absl::string_view s) : s(s) {}
+ explicit MyString(const char* s) : s(s) {}
+
+ template <typename H>
+ friend H AbslHashValue(H h, const MyString& s) {
+ return H::combine(std::move(h), s.s);
+ }
+
+ friend bool operator==(const MyString& lhs, const MyString& rhs) {
+ return lhs.s == rhs.s;
+ }
+ friend bool operator==(const MyString& lhs, absl::string_view rhs) {
+ return lhs.s == rhs;
+ }
+ friend bool operator==(absl::string_view lhs, const MyString& rhs) {
+ return lhs == rhs.s;
+ }
+};
+
+TEST(HashTest, TransparentHashDefaultLookUpAllowsImplicitCasting) {
+ EXPECT_EQ(
+ absl::Hash<absl::string_view>()("a"),
+ absl::TransparentHash<absl::string_view>()("a")
+ );
+ absl::flat_hash_set<std::string, absl::TransparentHash<absl::string_view>>
+ set;
+ set.insert("a");
+ EXPECT_TRUE(set.contains("a"));
+}
+
+TEST(HashTest, TransparentHashDefaultLookUpAllowsImplicitCastingMultiArg) {
+ using TestHash =
+ absl::TransparentHash<absl::string_view, MyString>;
+ EXPECT_EQ(absl::Hash<absl::string_view>()("a"), TestHash()("a"));
+ absl::flat_hash_set<MyString, TestHash, std::equal_to<>> set;
+ set.emplace("a");
+ EXPECT_TRUE(set.contains("a"));
+}
+
+struct Unhashable {};
+
+template <typename Hasher>
+class TransparentPoisonedHashTest : public testing::Test {};
+
+using TransparentPoisonedHashTypes =
+ testing::Types<absl::TransparentHash<Unhashable>,
+ absl::TransparentHash<Unhashable, Unhashable>,
+ absl::TransparentHash<int, Unhashable>,
+ absl::TransparentHash<int, Unhashable, int>,
+ absl::TransparentHash<int, Unhashable, int, Unhashable>>;
+TYPED_TEST_SUITE(TransparentPoisonedHashTest, TransparentPoisonedHashTypes);
+
+TYPED_TEST(TransparentPoisonedHashTest, PoisonHash) {
+ using Hasher = TypeParam;
+ EXPECT_FALSE(std::is_default_constructible_v<Hasher>);
+ EXPECT_FALSE(std::is_copy_constructible_v<Hasher>);
+ EXPECT_FALSE(std::is_move_constructible_v<Hasher>);
+ EXPECT_FALSE(std::is_copy_assignable_v<Hasher>);
+ EXPECT_FALSE(std::is_move_assignable_v<Hasher>);
+#if !defined(__GNUC__) || defined(__clang__)
+ // TODO(b/144368551): As of GCC 8.4 this does not compile.
+ EXPECT_FALSE(IsAggregateInitializable<Hasher>::value);
+#endif
+}
+
} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/hash_testing.h b/deps/v8/third_party/abseil-cpp/absl/hash/hash_testing.h
index d932f636623..8b233fd75bb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/hash_testing.h
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/hash_testing.h
@@ -26,6 +26,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/hash/internal/spy_hash_state.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/str_cat.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/city_test.cc b/deps/v8/third_party/abseil-cpp/absl/hash/internal/city_test.cc
index 822b39974d6..57b7aa74a6e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/city_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/city_test.cc
@@ -21,6 +21,7 @@
#include <iostream>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash.h b/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash.h
index a7dc74c60ff..590bf7f033c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash.h
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash.h
@@ -1569,6 +1569,8 @@ struct PoisonedHash : private AggregateBarrier {
PoisonedHash() = delete;
PoisonedHash(const PoisonedHash&) = delete;
PoisonedHash& operator=(const PoisonedHash&) = delete;
+ void operator()() const = delete;
+ size_t hash_with_seed() const = delete;
};
template <typename T>
@@ -1577,8 +1579,8 @@ struct HashImpl {
return MixingHashState::hash(value);
}
- private:
- friend struct HashWithSeed;
+ protected:
+ friend HashWithSeed;
size_t hash_with_seed(const T& value, size_t seed) const {
return MixingHashState::hash_with_seed(value, seed);
@@ -1589,6 +1591,58 @@ template <typename T>
struct Hash
: std::conditional_t<is_hashable<T>::value, HashImpl<T>, PoisonedHash> {};
+template <typename T, typename... Ts>
+inline constexpr bool pack_contains_v = (std::is_same_v<T, Ts> || ...);
+
+template <size_t>
+struct EmptyDuplicatedHash {
+ void operator()() const = delete;
+ size_t hash_with_seed() const = delete;
+};
+
+template <typename... Ts>
+class TransparentHashImpl;
+
+template <typename T>
+class TransparentHashImpl<T> : private Hash<T> {
+ public:
+ using Hash<T>::operator();
+ using Hash<T>::hash_with_seed;
+};
+
+template <typename T, typename... Ts>
+using TransparentHashImplSingle =
+ std::conditional_t<pack_contains_v<T, Ts...>,
+ EmptyDuplicatedHash<sizeof...(Ts)>, Hash<T>>;
+
+template <typename T, typename... Ts>
+class TransparentHashImpl<T, Ts...>
+ : private TransparentHashImpl<Ts...>,
+ private TransparentHashImplSingle<T, Ts...> {
+ public:
+ using TransparentHashImpl<Ts...>::operator();
+ using TransparentHashImplSingle<T, Ts...>::operator();
+ using TransparentHashImpl<Ts...>::hash_with_seed;
+ using TransparentHashImplSingle<T, Ts...>::hash_with_seed;
+};
+
+template <typename... Ts>
+using TransparentHashBase =
+ std::conditional_t<(... && is_hashable<Ts>::value),
+ TransparentHashImpl<Ts...>, PoisonedHash>;
+
+template <typename... Ts>
+class TransparentHash : private TransparentHashBase<Ts...> {
+ public:
+ using is_transparent = void;
+ using TransparentHashBase<Ts...>::operator();
+
+ private:
+ friend HashWithSeed;
+
+ using TransparentHashBase<Ts...>::hash_with_seed;
+};
+
template <typename H>
template <typename T, typename... Ts>
H HashStateBase<H>::combine(H state, const T& value, const Ts&... values) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h b/deps/v8/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
index 543e7197284..ae7d5955a87 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/spy_hash_state.h
@@ -26,6 +26,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/hash/hash.h"
#include "absl/hash/internal/weakly_mixed_integer.h"
#include "absl/strings/match.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel
index 188186622ad..2c0a8ffef4d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel
@@ -108,6 +108,7 @@ cc_library(
"//absl/log/internal:flags",
"//absl/log/internal:vlog_config",
"//absl/strings",
+ "//absl/strings:string_view",
],
# Binaries which do not access these flags from C++ still want this library linked in.
alwayslink = True,
@@ -128,7 +129,7 @@ cc_library(
"//absl/base:raw_logging_internal",
"//absl/hash",
"//absl/log/internal:vlog_config",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -173,6 +174,7 @@ cc_library(
"//absl/log/internal:config",
"//absl/log/internal:proto",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"//absl/types:span",
],
@@ -215,8 +217,8 @@ cc_library(
":absl_log",
"//absl/base:config",
"//absl/base:log_severity",
- "//absl/strings",
"//absl/strings:internal",
+ "//absl/strings:string_view",
"//absl/types:optional",
"//absl/types:source_location",
"//absl/utility",
@@ -238,7 +240,7 @@ cc_library(
"//absl/base:config",
"//absl/base:log_severity",
"//absl/base:raw_logging_internal",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
],
)
@@ -253,7 +255,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/log/internal:structured",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -267,7 +269,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/log/internal:vlog_config",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -494,6 +496,7 @@ cc_test(
"//absl/log/internal:format",
"//absl/log/internal:test_helpers",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"//absl/types:span",
"@googletest//:gtest",
@@ -511,12 +514,14 @@ cc_test(
":check",
":log",
":log_entry",
+ ":log_sink",
":scoped_mock_log",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/log/internal:test_matchers",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:source_location",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -561,7 +566,7 @@ cc_test(
"//absl/log/internal:test_actions",
"//absl/log/internal:test_helpers",
"//absl/log/internal:test_matchers",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -583,7 +588,7 @@ cc_test(
"//absl/log/internal:test_actions",
"//absl/log/internal:test_helpers",
"//absl/log/internal:test_matchers",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:source_location",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -606,6 +611,7 @@ cc_test(
"//absl/log/internal:test_helpers",
"//absl/log/internal:test_matchers",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"//absl/types:source_location",
"@googletest//:gtest",
@@ -636,6 +642,7 @@ cc_test(
"//absl/log/internal:test_matchers",
"//absl/memory",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -661,6 +668,7 @@ cc_test(
"//absl/status",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn
index d9d6f7a997b..017a39e6c57 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn
@@ -73,7 +73,6 @@ absl_source_set("globals") {
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/log/internal:vlog_config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -142,7 +141,6 @@ absl_source_set("log_streamer") {
":absl_log",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:log_severity",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:internal",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:optional",
@@ -162,7 +160,6 @@ absl_source_set("scoped_mock_log") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:log_severity",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
@@ -175,7 +172,6 @@ absl_source_set("structured") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/log/internal:structured",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -186,7 +182,6 @@ absl_source_set("absl_vlog_is_on") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/log/internal:vlog_config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -335,6 +330,7 @@ absl_test("log_format_test") {
":check",
":log",
":log_entry",
+ ":log_sink",
":scoped_mock_log",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -369,7 +365,6 @@ absl_test("log_sink_test") {
"//third_party/abseil-cpp/absl/log/internal:test_actions",
"//third_party/abseil-cpp/absl/log/internal:test_helpers",
"//third_party/abseil-cpp/absl/log/internal:test_matchers",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
if (is_ios) {
@@ -389,7 +384,6 @@ absl_test("log_streamer_test") {
"//third_party/abseil-cpp/absl/log/internal:test_actions",
"//third_party/abseil-cpp/absl/log/internal:test_helpers",
"//third_party/abseil-cpp/absl/log/internal:test_matchers",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:source_location",
]
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/log/CMakeLists.txt
index e0a307b3aff..ebc24f3bbf3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/log/CMakeLists.txt
@@ -17,7 +17,6 @@
absl_cc_library(
NAME
log_internal_check_impl
- SRCS
HDRS
"internal/check_impl.h"
COPTS
@@ -34,10 +33,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_check_op
- SRCS
- "internal/check_op.cc"
HDRS
"internal/check_op.h"
+ SRCS
+ "internal/check_op.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -52,16 +51,17 @@ absl_cc_library(
absl::log_internal_nullstream
absl::log_internal_strip
absl::nullability
+ absl::string_view
absl::strings
)
absl_cc_library(
NAME
log_internal_conditions
- SRCS
- "internal/conditions.cc"
HDRS
"internal/conditions.h"
+ SRCS
+ "internal/conditions.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -76,7 +76,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_config
- SRCS
HDRS
"internal/config.h"
COPTS
@@ -91,7 +90,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_flags
- SRCS
HDRS
"internal/flags.h"
COPTS
@@ -105,10 +103,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_format
- SRCS
- "internal/log_format.cc"
HDRS
"internal/log_format.h"
+ SRCS
+ "internal/log_format.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -120,19 +118,20 @@ absl_cc_library(
absl::log_internal_config
absl::log_internal_globals
absl::log_severity
- absl::strings
+ absl::span
absl::str_format
+ absl::string_view
+ absl::strings
absl::time
- absl::span
)
absl_cc_library(
NAME
log_internal_globals
- SRCS
- "internal/globals.cc"
HDRS
"internal/globals.h"
+ SRCS
+ "internal/globals.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -142,6 +141,7 @@ absl_cc_library(
absl::core_headers
absl::log_severity
absl::raw_logging_internal
+ absl::string_view
absl::strings
absl::time
)
@@ -149,7 +149,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_log_impl
- SRCS
HDRS
"internal/log_impl.h"
COPTS
@@ -157,19 +156,19 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::absl_vlog_is_on
absl::log_internal_conditions
absl::log_internal_message
absl::log_internal_strip
- absl::absl_vlog_is_on
)
absl_cc_library(
NAME
log_internal_proto
- SRCS
- "internal/proto.cc"
HDRS
"internal/proto.h"
+ SRCS
+ "internal/proto.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -178,17 +177,17 @@ absl_cc_library(
absl::base
absl::config
absl::core_headers
- absl::strings
absl::span
+ absl::string_view
)
absl_cc_library(
NAME
log_internal_message
- SRCS
- "internal/log_message.cc"
HDRS
"internal/log_message.h"
+ SRCS
+ "internal/log_message.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -200,15 +199,15 @@ absl_cc_library(
absl::errno_saver
absl::examine_stack
absl::inlined_vector
+ absl::log_entry
+ absl::log_globals
absl::log_internal_append_truncated
absl::log_internal_format
absl::log_internal_globals
- absl::log_internal_proto
absl::log_internal_log_sink_set
absl::log_internal_nullguard
+ absl::log_internal_proto
absl::log_internal_structured_proto
- absl::log_globals
- absl::log_entry
absl::log_severity
absl::log_sink
absl::log_sink_registry
@@ -226,10 +225,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_log_sink_set
- SRCS
- "internal/log_sink_set.cc"
HDRS
"internal/log_sink_set.h"
+ SRCS
+ "internal/log_sink_set.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -240,26 +239,26 @@ absl_cc_library(
absl::cleanup
absl::config
absl::core_headers
+ absl::log_entry
+ absl::log_globals
absl::log_internal_config
absl::log_internal_globals
- absl::log_globals
- absl::log_entry
absl::log_severity
absl::log_sink
absl::no_destructor
absl::raw_logging_internal
- absl::synchronization
absl::span
- absl::strings
+ absl::string_view
+ absl::synchronization
)
absl_cc_library(
NAME
log_internal_nullguard
- SRCS
- "internal/nullguard.cc"
HDRS
"internal/nullguard.h"
+ SRCS
+ "internal/nullguard.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -272,7 +271,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_nullstream
- SRCS
HDRS
"internal/nullstream.h"
COPTS
@@ -283,13 +281,12 @@ absl_cc_library(
absl::config
absl::core_headers
absl::log_severity
- absl::strings
+ absl::string_view
)
absl_cc_library(
NAME
log_internal_strip
- SRCS
HDRS
"internal/strip.h"
COPTS
@@ -306,10 +303,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_test_actions
- SRCS
- "internal/test_actions.cc"
HDRS
"internal/test_actions.h"
+ SRCS
+ "internal/test_actions.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -319,6 +316,7 @@ absl_cc_library(
absl::core_headers
absl::log_entry
absl::log_severity
+ absl::string_view
absl::strings
absl::time
TESTONLY
@@ -327,10 +325,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_test_helpers
- SRCS
- "internal/test_helpers.cc"
HDRS
"internal/test_helpers.h"
+ SRCS
+ "internal/test_helpers.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -348,10 +346,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_test_matchers
- SRCS
- "internal/test_matchers.cc"
HDRS
"internal/test_matchers.h"
+ SRCS
+ "internal/test_matchers.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -362,17 +360,16 @@ absl_cc_library(
absl::log_entry
absl::log_internal_test_helpers
absl::log_severity
- absl::strings
+ absl::string_view
absl::time
- GTest::gtest
GTest::gmock
+ GTest::gtest
TESTONLY
)
absl_cc_library(
NAME
log_internal_voidify
- SRCS
HDRS
"internal/voidify.h"
COPTS
@@ -387,7 +384,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_internal_append_truncated
- SRCS
HDRS
"internal/append_truncated.h"
COPTS
@@ -396,16 +392,15 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::strings
- absl::strings_internal
absl::span
+ absl::string_view
+ absl::strings_internal
)
# Public targets
absl_cc_library(
NAME
absl_check
- SRCS
HDRS
"absl_check.h"
COPTS
@@ -420,7 +415,6 @@ absl_cc_library(
absl_cc_library(
NAME
absl_log
- SRCS
HDRS
"absl_log.h"
COPTS
@@ -435,7 +429,6 @@ absl_cc_library(
absl_cc_library(
NAME
check
- SRCS
HDRS
"check.h"
COPTS
@@ -443,8 +436,8 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::log_internal_check_impl
absl::core_headers
+ absl::log_internal_check_impl
absl::log_internal_check_op
absl::log_internal_conditions
absl::log_internal_message
@@ -455,10 +448,10 @@ absl_cc_library(
absl_cc_library(
NAME
die_if_null
- SRCS
- "die_if_null.cc"
HDRS
"die_if_null.h"
+ SRCS
+ "die_if_null.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -481,10 +474,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_flags
- SRCS
- "flags.cc"
HDRS
"flags.h"
+ SRCS
+ "flags.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -492,12 +485,12 @@ absl_cc_library(
DEPS
absl::config
absl::core_headers
+ absl::flags
+ absl::flags_marshalling
absl::log_globals
- absl::log_severity
absl::log_internal_config
absl::log_internal_flags
- absl::flags
- absl::flags_marshalling
+ absl::log_severity
absl::strings
absl::vlog_config_internal
PUBLIC
@@ -506,10 +499,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_globals
- SRCS
- "globals.cc"
HDRS
"globals.h"
+ SRCS
+ "globals.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -528,10 +521,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_initialize
- SRCS
- "initialize.cc"
HDRS
"initialize.h"
+ SRCS
+ "initialize.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -547,7 +540,6 @@ absl_cc_library(
absl_cc_library(
NAME
log
- SRCS
HDRS
"log.h"
COPTS
@@ -563,10 +555,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_entry
- SRCS
- "log_entry.cc"
HDRS
"log_entry.h"
+ SRCS
+ "log_entry.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -578,6 +570,7 @@ absl_cc_library(
absl::log_internal_proto
absl::log_severity
absl::span
+ absl::string_view
absl::strings
absl::time
PUBLIC
@@ -586,10 +579,10 @@ absl_cc_library(
absl_cc_library(
NAME
log_sink
- SRCS
- "log_sink.cc"
HDRS
"log_sink.h"
+ SRCS
+ "log_sink.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -603,7 +596,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_sink_registry
- SRCS
HDRS
"log_sink_registry.h"
COPTS
@@ -612,8 +604,8 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::log_sink
absl::log_internal_log_sink_set
+ absl::log_sink
absl::nullability
PUBLIC
)
@@ -621,7 +613,6 @@ absl_cc_library(
absl_cc_library(
NAME
log_streamer
- SRCS
HDRS
"log_streamer.h"
COPTS
@@ -629,12 +620,12 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::config
absl::absl_log
+ absl::config
absl::log_severity
absl::optional
absl::source_location
- absl::strings
+ absl::string_view
absl::strings_internal
absl::utility
PUBLIC
@@ -643,10 +634,10 @@ absl_cc_library(
absl_cc_library(
NAME
scoped_mock_log
- SRCS
- "scoped_mock_log.cc"
HDRS
"scoped_mock_log.h"
+ SRCS
+ "scoped_mock_log.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -658,7 +649,7 @@ absl_cc_library(
absl::log_sink
absl::log_sink_registry
absl::raw_logging_internal
- absl::strings
+ absl::string_view
GTest::gmock
GTest::gtest
PUBLIC
@@ -680,25 +671,25 @@ absl_cc_library(
absl::core_headers
absl::log_internal_message
absl::log_internal_structured_proto
+ absl::string_view
absl::strings
)
absl_cc_library(
NAME
log_internal_structured_proto
- SRCS
- "internal/structured_proto.cc"
HDRS
"internal/structured_proto.h"
+ SRCS
+ "internal/structured_proto.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::log_internal_proto
absl::config
+ absl::log_internal_proto
absl::span
- absl::strings
absl::variant
PUBLIC
)
@@ -741,10 +732,10 @@ absl_cc_library(
absl_cc_library(
NAME
vlog_config_internal
- SRCS
- "internal/vlog_config.cc"
HDRS
"internal/vlog_config.h"
+ SRCS
+ "internal/vlog_config.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -771,10 +762,10 @@ absl_cc_library(
HDRS
"absl_vlog_is_on.h"
DEPS
- absl::vlog_config_internal
absl::config
absl::core_headers
- absl::strings
+ absl::string_view
+ absl::vlog_config_internal
)
absl_cc_library(
@@ -800,30 +791,30 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::flags
absl::log
absl::log_flags
absl::log_globals
+ absl::log_severity
absl::scoped_mock_log
absl::vlog_is_on
- absl::log_severity
- absl::flags
GTest::gmock_main
)
absl_cc_library(
NAME
log_internal_fnmatch
- SRCS
- "internal/fnmatch.cc"
HDRS
"internal/fnmatch.h"
+ SRCS
+ "internal/fnmatch.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::strings
+ absl::string_view
)
# Test targets
@@ -844,8 +835,8 @@ absl_cc_test(
absl::core_headers
absl::log_internal_test_helpers
absl::status
- absl::strings
absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -860,15 +851,15 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::base
absl::absl_log
+ absl::base
absl::log_entry
absl::log_globals
- absl::log_severity
absl::log_internal_globals
absl::log_internal_test_actions
absl::log_internal_test_helpers
absl::log_internal_test_matchers
+ absl::log_severity
absl::scoped_mock_log
GTest::gmock_main
)
@@ -889,8 +880,8 @@ absl_cc_test(
absl::core_headers
absl::log_internal_test_helpers
absl::status
- absl::strings
absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -925,10 +916,10 @@ absl_cc_test(
absl::log
absl::log_entry
absl::log_globals
- absl::log_severity
absl::log_internal_test_actions
absl::log_internal_test_helpers
absl::log_internal_test_matchers
+ absl::log_severity
absl::scoped_mock_log
GTest::gmock_main
)
@@ -952,6 +943,7 @@ absl_cc_test(
absl::log_internal_test_helpers
absl::log_severity
absl::span
+ absl::string_view
absl::strings
absl::time
GTest::gmock_main
@@ -968,6 +960,8 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::core_headers
+ absl::flags
+ absl::flags_reflection
absl::log
absl::log_flags
absl::log_globals
@@ -975,8 +969,6 @@ absl_cc_test(
absl::log_internal_test_helpers
absl::log_internal_test_matchers
absl::log_severity
- absl::flags
- absl::flags_reflection
absl::scoped_mock_log
absl::strings
GTest::gmock_main
@@ -1016,9 +1008,11 @@ absl_cc_test(
absl::config
absl::log
absl::log_internal_test_matchers
+ absl::log_sink
absl::scoped_mock_log
absl::source_location
absl::str_format
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -1055,11 +1049,11 @@ absl_cc_test(
absl::log_internal_test_actions
absl::log_internal_test_helpers
absl::log_internal_test_matchers
+ absl::log_severity
absl::log_sink
absl::log_sink_registry
- absl::log_severity
absl::scoped_mock_log
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -1079,11 +1073,11 @@ absl_cc_test(
absl::log_internal_test_actions
absl::log_internal_test_helpers
absl::log_internal_test_matchers
- absl::log_streamer
absl::log_severity
+ absl::log_streamer
absl::scoped_mock_log
absl::source_location
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -1104,6 +1098,7 @@ absl_cc_test(
absl::log_sink
absl::scoped_mock_log
absl::source_location
+ absl::string_view
absl::strings
absl::time
GTest::gmock_main
@@ -1128,6 +1123,7 @@ absl_cc_test(
absl::log_severity
absl::memory
absl::scoped_mock_log
+ absl::string_view
absl::strings
absl::synchronization
GTest::gmock
@@ -1168,9 +1164,9 @@ absl_cc_test(
absl::log_internal_test_helpers
absl::log_severity
absl::status
+ absl::str_format
absl::strerror
absl::strings
- absl::str_format
GTest::gmock_main
)
@@ -1235,7 +1231,7 @@ absl_cc_test(
absl::config
absl::log_internal_container
absl::span
- absl::strings
absl::str_format
+ absl::strings
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/die_if_null_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/die_if_null_test.cc
index b0aab781c36..1956ffa6189 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/die_if_null_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/die_if_null_test.cc
@@ -26,7 +26,7 @@
namespace {
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
// TODO(b/69907837): Revisit these tests with the goal of making them less
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/flags.cc b/deps/v8/third_party/abseil-cpp/absl/log/flags.cc
index 287b3e96c70..36a56b314b4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/flags.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/flags.cc
@@ -47,7 +47,7 @@ bool RegisterSyncLoggingFlags() {
return true;
}
-ABSL_ATTRIBUTE_UNUSED const bool unused = RegisterSyncLoggingFlags();
+[[maybe_unused]] const bool unused = RegisterSyncLoggingFlags();
template <typename T>
T GetFromEnv(const char* varname, T dflt) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/flags_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/flags_test.cc
index f5a2b5189c7..6bb4fed0d71 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/flags_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/flags_test.cc
@@ -36,7 +36,7 @@ using ::absl::log_internal::TextMessage;
using ::testing::HasSubstr;
using ::testing::Not;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
constexpr static absl::LogSeverityAtLeast DefaultStderrThreshold() {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/globals_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/globals_test.cc
index 78430d460f9..f7fbd2bbb23 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/globals_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/globals_test.cc
@@ -28,7 +28,7 @@ namespace {
using ::testing::_;
using ::testing::StrEq;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
constexpr static absl::LogSeverityAtLeast DefaultMinLogLevel() {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.bazel
index d9cb7b20f70..42114edb61a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.bazel
@@ -85,6 +85,7 @@ cc_library(
"//absl/debugging:leak_check",
"//absl/strings",
"//absl/strings:has_ostream_operator",
+ "//absl/strings:string_view",
],
)
@@ -144,6 +145,7 @@ cc_library(
"//absl/base:log_severity",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/time",
"//absl/types:span",
],
@@ -165,6 +167,7 @@ cc_library(
"//absl/base:log_severity",
"//absl/base:raw_logging_internal",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
],
)
@@ -216,6 +219,7 @@ cc_library(
"//absl/log:log_sink_registry",
"//absl/strings",
"//absl/strings:internal",
+ "//absl/strings:string_view",
"//absl/time",
"//absl/types:source_location",
"//absl/types:span",
@@ -229,8 +233,8 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base:config",
- "//absl/strings",
"//absl/strings:internal",
+ "//absl/strings:string_view",
"//absl/types:span",
],
)
@@ -257,7 +261,7 @@ cc_library(
"//absl/log:globals",
"//absl/log:log_entry",
"//absl/log:log_sink",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
"//absl/types:span",
],
@@ -284,7 +288,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:log_severity",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -318,6 +322,7 @@ cc_library(
"//absl/base:core_headers",
"//absl/functional:any_invocable",
"//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -333,7 +338,6 @@ cc_library(
deps = [
":proto",
"//absl/base:config",
- "//absl/strings",
"//absl/types:span",
"//absl/types:variant",
],
@@ -365,6 +369,7 @@ cc_library(
"//absl/base:log_severity",
"//absl/log:log_entry",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
] + select({
"@rules_cc//cc/compiler:msvc-cl": [],
@@ -413,7 +418,7 @@ cc_library(
"//absl/base:core_headers",
"//absl/base:log_severity",
"//absl/log:log_entry",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/time",
"@googletest//:gtest",
] + select({
@@ -444,7 +449,7 @@ cc_library(
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:span",
],
)
@@ -457,7 +462,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base:config",
- "//absl/strings",
+ "//absl/strings:string_view",
],
)
@@ -481,6 +486,7 @@ cc_library(
"//absl/base:no_destructor",
"//absl/base:nullability",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/synchronization",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.gn
index 9b9645ce387..d6e2456ee9f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/BUILD.gn
@@ -176,7 +176,6 @@ absl_source_set("append_truncated") {
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:internal",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:span",
@@ -203,7 +202,6 @@ absl_source_set("log_sink_set") {
"//third_party/abseil-cpp/absl/log:globals",
"//third_party/abseil-cpp/absl/log:log_entry",
"//third_party/abseil-cpp/absl/log:log_sink",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/types:span",
@@ -236,7 +234,6 @@ absl_source_set("nullstream") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:log_severity",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -283,7 +280,6 @@ absl_source_set("structured_proto") {
deps = [
":proto",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/abseil-cpp/absl/types:variant",
]
@@ -353,7 +349,6 @@ absl_source_set("test_matchers") {
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:log_severity",
"//third_party/abseil-cpp/absl/log:log_entry",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/time",
"//third_party/googletest:gmock",
@@ -384,7 +379,6 @@ absl_source_set("proto") {
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:span",
]
@@ -399,7 +393,6 @@ absl_source_set("fnmatch") {
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/conditions.h b/deps/v8/third_party/abseil-cpp/absl/log/internal/conditions.h
index 8be029d58db..f63e70974af 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/conditions.h
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/conditions.h
@@ -94,7 +94,7 @@
absl_log_internal_stateful_condition_do_log && \
absl_log_internal_stateful_condition_state.ShouldLog(__VA_ARGS__); \
absl_log_internal_stateful_condition_do_log = false) \
- for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED = \
+ for (const uint32_t COUNTER [[maybe_unused]] = \
absl_log_internal_stateful_condition_state.counter(); \
absl_log_internal_stateful_condition_do_log; \
absl_log_internal_stateful_condition_do_log = false) \
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch.cc
index 26e1e57fe43..ee77a4f3ea9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch.cc
@@ -23,50 +23,40 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
bool FNMatch(absl::string_view pattern, absl::string_view str) {
- bool in_wildcard_match = false;
- while (true) {
- if (pattern.empty()) {
- // `pattern` is exhausted; succeed if all of `str` was consumed matching
- // it.
- return in_wildcard_match || str.empty();
- }
- if (str.empty()) {
- // `str` is exhausted; succeed if `pattern` is empty or all '*'s.
- return pattern.find_first_not_of('*') == pattern.npos;
- }
- switch (pattern.front()) {
- case '*':
- pattern.remove_prefix(1);
- in_wildcard_match = true;
- break;
- case '?':
- pattern.remove_prefix(1);
- str.remove_prefix(1);
- break;
- default:
- if (in_wildcard_match) {
- absl::string_view fixed_portion = pattern;
- const size_t end = fixed_portion.find_first_of("*?");
- if (end != fixed_portion.npos) {
- fixed_portion = fixed_portion.substr(0, end);
- }
- const size_t match = str.find(fixed_portion);
- if (match == str.npos) {
- return false;
- }
- pattern.remove_prefix(fixed_portion.size());
- str.remove_prefix(match + fixed_portion.size());
- in_wildcard_match = false;
- } else {
- if (pattern.front() != str.front()) {
- return false;
- }
- pattern.remove_prefix(1);
- str.remove_prefix(1);
- }
- break;
+ // Two-pointer glob matcher: '?' matches exactly one character and '*' matches
+ // any run of characters (including the empty run). We remember the position
+ // just after the most recent '*' so that, on a later mismatch, that '*' can
+ // consume one more character of `str` and the match be retried.
+ size_t p = 0; // Current position in `pattern`.
+ size_t s = 0; // Current position in `str`.
+ // `pattern` position just after the most recent '*', and the `str` position
+ // when it was seen; `npos` until a '*' has been encountered.
+ size_t star_p = absl::string_view::npos;
+ size_t star_s = 0;
+ while (s < str.size()) {
+ if (p < pattern.size() && pattern[p] == '*') {
+ // Found '*'. Record checkpoint after '*' and advance pattern index only.
+ star_p = ++p;
+ star_s = s;
+ } else if (p < pattern.size() &&
+ (pattern[p] == '?' || pattern[p] == str[s])) {
+ // Literal character match or single-character wildcard '?'. Advance both
+ // pattern and string pointers.
+ ++p;
+ ++s;
+ } else if (star_p != absl::string_view::npos) {
+ // Mismatch, but a preceding '*' exists. Backtrack: reset pattern to after
+ // the '*', and let that '*' consume one more character.
+ p = star_p;
+ s = ++star_s;
+ } else {
+ // Mismatch and no preceding '*' exists to absorb it.
+ return false;
}
}
+ // `str` is exhausted; the remainder of `pattern` must be all '*'s.
+ while (p < pattern.size() && pattern[p] == '*') ++p;
+ return p == pattern.size();
}
} // namespace log_internal
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch_test.cc
index 614c7d35edc..27611e387b4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/fnmatch_test.cc
@@ -57,4 +57,19 @@ TEST(FNMatchTest, Works) {
EXPECT_THAT(FNMatch("*?", "*"), IsTrue());
}
+TEST(FNMatchTest, BacktracksAfterStar) {
+ using absl::log_internal::FNMatch;
+ // A literal run after '*' may occur more than once in `str`; the match must
+ // not commit to the first occurrence.
+ EXPECT_THAT(FNMatch("*test", "testtest"), IsTrue());
+ EXPECT_THAT(FNMatch("*.cc", "aa.cc.cc"), IsTrue());
+ EXPECT_THAT(FNMatch("*_test", "unit_test_test"), IsTrue());
+ EXPECT_THAT(FNMatch("*aa", "aaa"), IsTrue());
+ EXPECT_THAT(FNMatch("*a*b", "aXaXb"), IsTrue());
+ EXPECT_THAT(FNMatch("*ab*ab", "abXab"), IsTrue());
+ // Backtracking must still reject genuine non-matches.
+ EXPECT_THAT(FNMatch("*test", "testtes"), IsFalse());
+ EXPECT_THAT(FNMatch("*_test", "unit_tests"), IsFalse());
+}
+
} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_message.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_message.cc
index 8ac81dfed0d..4e5da95a0aa 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_message.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_message.cc
@@ -219,7 +219,8 @@ LogMessage::LogMessageData::LogMessageData(absl::string_view file,
void LogMessage::LogMessageData::InitializeEncodingAndFormat() {
EncodeStringTruncate(EventTag::kFileName, entry.source_filename(),
&encoded_remaining());
- EncodeVarint(EventTag::kFileLine, entry.source_line(), &encoded_remaining());
+ EncodeVarint(EventTag::kFileLine, static_cast<int32_t>(entry.source_line()),
+ &encoded_remaining());
EncodeVarint(EventTag::kTimeNsecs, absl::ToUnixNanos(entry.timestamp()),
&encoded_remaining());
EncodeVarint(EventTag::kSeverity,
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/proto.h b/deps/v8/third_party/abseil-cpp/absl/log/internal/proto.h
index 23f79543231..d2700ee0007 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/proto.h
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/proto.h
@@ -79,6 +79,9 @@ inline bool EncodeVarint(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
inline bool EncodeVarint(uint64_t tag, int32_t value, absl::Span<char> *buf) {
return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
}
+inline bool EncodeVarint(uint64_t tag, bool value, absl::Span<char>* buf) {
+ return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
+}
// Encodes the specified integer as a varint field using ZigZag encoding and
// returns true if it fits.
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/stderr_log_sink_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/stderr_log_sink_test.cc
index 763690d1b32..4e5787e2b78 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/stderr_log_sink_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/stderr_log_sink_test.cc
@@ -29,7 +29,7 @@ namespace {
using ::testing::AllOf;
using ::testing::HasSubstr;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
MATCHER_P2(HasSubstrTimes, substr, expected_count, "") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/structured_proto_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/structured_proto_test.cc
index 80a3e7b6b5b..32a57c0ede8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/structured_proto_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/structured_proto_test.cc
@@ -76,6 +76,17 @@ INSTANTIATE_TEST_SUITE_P(
},
{'\xD0', '\x02', '\x17'},
},
+ {
+ "VarintBool",
+ {
+ 42,
+ StructuredProtoField::Value{
+ std::in_place_type<StructuredProtoField::Varint>,
+ true,
+ },
+ },
+ {'\xD0', '\x02', '\x01'},
+ },
{
"I64",
{
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_benchmark.cc
index 60c0fd637e4..50a64ea1649 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_benchmark.cc
@@ -88,7 +88,7 @@ static void BM_EnabledLogOverhead(benchmark::State& state) {
absl::LogSeverityAtLeast::kInfinity);
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
absl::LogSeverityAtLeast::kInfo);
- ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
+ [[maybe_unused]] NullLogSink null_sink;
for (auto _ : state) {
LOG(INFO);
}
@@ -143,7 +143,7 @@ static void BM_LogEveryNOverhead(benchmark::State& state) {
absl::ScopedStderrThreshold disable_stderr_logging(
absl::LogSeverityAtLeast::kInfinity);
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfinity);
- ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
+ [[maybe_unused]] NullLogSink null_sink;
while (state.KeepRunningBatch(10)) {
LOG_EVERY_N_SEC(INFO, 10);
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_entry_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_entry_test.cc
index 3af10b65fce..4b3af4c4b03 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_entry_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_entry_test.cc
@@ -47,7 +47,7 @@ using ::testing::IsTrue;
using ::testing::StartsWith;
using ::testing::StrEq;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_format_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_format_test.cc
index eb7585c158a..b792d384ace 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_format_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_format_test.cc
@@ -34,6 +34,7 @@
#include "absl/log/internal/test_matchers.h"
#include "absl/log/log.h"
#include "absl/log/log_entry.h"
+#include "absl/log/log_sink.h"
#include "absl/log/scoped_mock_log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
@@ -1273,7 +1274,7 @@ struct PointWithAbslStringifiyAndOstream {
int y = 20;
};
-ABSL_ATTRIBUTE_UNUSED std::ostream& operator<<(
+[[maybe_unused]] std::ostream& operator<<(
std::ostream& os, const PointWithAbslStringifiyAndOstream&) {
return os << "Default to AbslStringify()";
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_macro_hygiene_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_macro_hygiene_test.cc
index dad9389e741..e3f813c9d62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_macro_hygiene_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_macro_hygiene_test.cc
@@ -77,7 +77,7 @@ TEST(LogHygieneTest, WorksForQualifiedSeverity) {
}
TEST(LogHygieneTest, WorksWithAlternativeINFOSymbol) {
- const double INFO ABSL_ATTRIBUTE_UNUSED = 7.77;
+ const double INFO [[maybe_unused]] = 7.77;
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"));
@@ -87,7 +87,7 @@ TEST(LogHygieneTest, WorksWithAlternativeINFOSymbol) {
}
TEST(LogHygieneTest, WorksWithAlternativeWARNINGSymbol) {
- const double WARNING ABSL_ATTRIBUTE_UNUSED = 7.77;
+ const double WARNING [[maybe_unused]] = 7.77;
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "Hello world"));
@@ -97,7 +97,7 @@ TEST(LogHygieneTest, WorksWithAlternativeWARNINGSymbol) {
}
TEST(LogHygieneTest, WorksWithAlternativeERRORSymbol) {
- const double ERROR ABSL_ATTRIBUTE_UNUSED = 7.77;
+ const double ERROR [[maybe_unused]] = 7.77;
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
@@ -107,7 +107,7 @@ TEST(LogHygieneTest, WorksWithAlternativeERRORSymbol) {
}
TEST(LogHygieneTest, WorksWithAlternativeLEVELSymbol) {
- const double LEVEL ABSL_ATTRIBUTE_UNUSED = 7.77;
+ const double LEVEL [[maybe_unused]] = 7.77;
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_sink_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_sink_test.cc
index cbb5a531b60..82961db1f47 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_sink_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_sink_test.cc
@@ -39,7 +39,7 @@ using ::testing::AnyNumber;
using ::testing::HasSubstr;
using ::testing::InSequence;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
// Tests for global log sink registration.
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_streamer_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_streamer_test.cc
index e45a2935280..a6f41c04106 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_streamer_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_streamer_test.cc
@@ -55,7 +55,7 @@ using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::IsTrue;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
void WriteToStream(absl::string_view data, std::ostream* os) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/scoped_mock_log_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/scoped_mock_log_test.cc
index 6f1d8fb7fc4..31bcdc59d67 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/scoped_mock_log_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/scoped_mock_log_test.cc
@@ -49,7 +49,7 @@ using absl::log_internal::SourceLine;
using absl::log_internal::TextMessageWithPrefix;
using absl::log_internal::ThreadID;
-auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
#if GTEST_HAS_DEATH_TEST
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/structured_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/structured_test.cc
index cde81999a68..a68ec99634e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/structured_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/structured_test.cc
@@ -33,7 +33,7 @@ using ::absl::log_internal::TextMessage;
using ::testing::ElementsAre;
using ::testing::Eq;
-auto *test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
+auto* test_env [[maybe_unused]] = ::testing::AddGlobalTestEnvironment(
new absl::log_internal::LogTestEnvironment);
// Abseil Logging library uses these by default, so we set them on the
diff --git a/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.bazel
index 92f93729392..76fee58141c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.bazel
@@ -44,6 +44,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = ["//visibility:public"],
deps = [
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn
index 7d9b7c67171..fdf021fcc04 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn
@@ -9,6 +9,7 @@ import("//third_party/abseil-cpp/absl.gni")
absl_source_set("memory") {
public = [ "memory.h" ]
deps = [
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
diff --git a/deps/v8/third_party/abseil-cpp/absl/memory/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/memory/CMakeLists.txt
index c5ed4b42558..f6a05f67793 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/CMakeLists.txt
@@ -35,7 +35,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::memory
absl::core_headers
+ absl::memory
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/memory/memory.h b/deps/v8/third_party/abseil-cpp/absl/memory/memory.h
index cbc98125099..5774be7a96f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/memory.h
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/memory.h
@@ -31,6 +31,7 @@
#include <utility>
#include <version>
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/meta/CMakeLists.txt
index c98c360439a..644fc1b5d62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/CMakeLists.txt
@@ -82,8 +82,8 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::config
- absl::time
absl::core_headers
+ absl::time
absl::type_traits
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing_test.cc b/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing_test.cc
index 50c8c53d0ae..761a0816d67 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing_test.cc
@@ -14,6 +14,7 @@
#include "absl/meta/internal/constexpr_testing.h"
+#include <cstdlib>
#include <map>
#include <string_view>
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/type_traits.h b/deps/v8/third_party/abseil-cpp/absl/meta/type_traits.h
index 3739919857c..aac9a306c64 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/type_traits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/type_traits.h
@@ -45,6 +45,7 @@
#include <utility>
#include <variant>
#include <vector>
+#include <version>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.bazel
index d61606c0f5d..bc9670df8a3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.bazel
@@ -73,6 +73,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bits",
+ "//absl/base:config",
"//absl/random",
"@googletest//:gtest",
"@googletest//:gtest_main",
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn
index cae5a16677c..5b9c026ec08 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn
@@ -22,6 +22,7 @@ absl_test("bits_test") {
sources = [ "bits_test.cc" ]
deps = [
":bits",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/random",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/numeric/CMakeLists.txt
index 68446b012b5..a03d548df89 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/CMakeLists.txt
@@ -55,10 +55,10 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::bits
absl::compare
absl::config
absl::core_headers
- absl::bits
PUBLIC
)
@@ -71,12 +71,12 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::int128
absl::base
absl::compare
absl::hash_testing
- absl::type_traits
+ absl::int128
absl::strings
+ absl::type_traits
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/bits_test.cc b/deps/v8/third_party/abseil-cpp/absl/numeric/bits_test.cc
index 30b59671cd7..401de897836 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/bits_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/bits_test.cc
@@ -20,6 +20,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/numeric/internal/bits.h"
#include "absl/random/random.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc b/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc
index dc01c0fae8d..a58b772f068 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc
@@ -27,6 +27,7 @@
#include <type_traits>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/numeric/bits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel
index e958307e4ec..2d9ecc61d8d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel
@@ -59,6 +59,7 @@ cc_test(
],
deps = [
":sample_recorder",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/random",
"//absl/synchronization",
@@ -93,6 +94,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":exponential_biased",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/strings",
"@googletest//:gtest",
@@ -111,6 +113,7 @@ cc_library(
],
deps = [
":exponential_biased",
+ "//absl/base:config",
"//absl/base:core_headers",
],
)
@@ -124,6 +127,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":periodic_sampler",
+ "//absl/base:config",
"//absl/base:core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -140,6 +144,7 @@ cc_binary(
visibility = ["//visibility:private"],
deps = [
":periodic_sampler",
+ "//absl/base:config",
"//absl/base:core_headers",
"@google_benchmark//:benchmark_main",
],
@@ -163,6 +168,7 @@ cc_library(
"//absl/container:hash_container_defaults",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:span",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn
index d81253ad545..303b5f46f4c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn
@@ -35,6 +35,7 @@ absl_test("exponential_biased_test") {
sources = [ "internal/exponential_biased_test.cc" ]
deps = [
":exponential_biased",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
]
@@ -46,6 +47,7 @@ absl_source_set("periodic_sampler") {
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":exponential_biased",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
@@ -54,6 +56,7 @@ absl_test("periodic_sampler_test") {
sources = [ "internal/periodic_sampler_test.cc" ]
deps = [
":periodic_sampler",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/profiling/CMakeLists.txt
index 6441daec852..01691829716 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/CMakeLists.txt
@@ -41,10 +41,10 @@ absl_cc_test(
absl_cc_library(
NAME
exponential_biased
- SRCS
- "internal/exponential_biased.cc"
HDRS
"internal/exponential_biased.h"
+ SRCS
+ "internal/exponential_biased.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -68,10 +68,10 @@ absl_cc_test(
absl_cc_library(
NAME
periodic_sampler
- SRCS
- "internal/periodic_sampler.cc"
HDRS
"internal/periodic_sampler.h"
+ SRCS
+ "internal/periodic_sampler.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -103,14 +103,15 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::btree
absl::config
absl::core_headers
- absl::raw_logging_internal
absl::flat_hash_map
- absl::btree
- absl::strings
- absl::str_format
+ absl::raw_logging_internal
absl::span
+ absl::str_format
+ absl::string_view
+ absl::strings
)
absl_cc_library(
@@ -123,10 +124,10 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::profile_builder
absl::config
absl::core_headers
- absl::strings
- absl::span
absl::hashtablez_sampler
+ absl::profile_builder
+ absl::span
+ absl::strings
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.h b/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.h
index 9e490dcdb8a..396dff5b3af 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.h
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.h
@@ -18,6 +18,7 @@
#include <cstdint>
#include <string>
+#include "absl/base/config.h"
#include "absl/container/internal/hashtablez_sampler.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc
index 918d063aaae..8682ca15e7b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc
@@ -22,6 +22,7 @@
#include <limits>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased_test.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased_test.cc
index 103b7d543d8..3471b071064 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/exponential_biased_test.cc
@@ -26,6 +26,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/strings/str_cat.h"
using ::testing::Ge;
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
index 3e0fc2f13d2..20f2001eac0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.cc
@@ -17,6 +17,7 @@
#include <atomic>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/profiling/internal/exponential_biased.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.h b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.h
index f5d847ab254..0b4c500b0d2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.h
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler.h
@@ -19,6 +19,7 @@
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/profiling/internal/exponential_biased.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_benchmark.cc
index 2d6beca8d64..b468b41a6d7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_benchmark.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/profiling/internal/periodic_sampler.h"
#include "benchmark/benchmark.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_test.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_test.cc
index d89b21724cd..546454d710e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/periodic_sampler_test.cc
@@ -20,6 +20,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.h b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.h
index 243b927c541..7ab3eb630ca 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.h
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.h
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/hash_container_defaults.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
index 2401149c8e0..4e1437ed8fa 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder_test.cc
@@ -24,6 +24,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/base/thread_annotations.h"
#include "absl/random/random.h"
#include "absl/synchronization/internal/thread_pool.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel
index 7d62fa51932..edc4e9393a7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel
@@ -89,6 +89,7 @@ cc_library(
"//absl/random/internal:uniform_helper",
"//absl/random/internal:wide_multiply",
"//absl/strings",
+ "//absl/strings:string_view",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn
index 2b76e0bf95f..c3bf3a9076d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn
@@ -50,6 +50,7 @@ absl_source_set("distributions") {
"//third_party/abseil-cpp/absl/random/internal:uniform_helper",
"//third_party/abseil-cpp/absl/random/internal:wide_multiply",
"//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/random/CMakeLists.txt
index 4a13e84e7db..914ba0fcf1b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/random/CMakeLists.txt
@@ -45,9 +45,9 @@ absl_cc_library(
absl::config
absl::core_headers
absl::random_internal_fast_uniform_bits
- absl::type_traits
- absl::random_mocking_access
absl::random_internal_traits
+ absl::random_mocking_access
+ absl::type_traits
)
absl_cc_test(
@@ -61,10 +61,10 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
+ absl::fast_type_id
absl::random_bit_gen_ref
- absl::random_random
absl::random_internal_sequence_urbg
- absl::fast_type_id
+ absl::random_random
GTest::gmock
GTest::gtest_main
)
@@ -113,8 +113,8 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::random_mocking_bit_gen
absl::random_internal_mock_helpers
+ absl::random_mocking_bit_gen
TESTONLY
)
@@ -133,10 +133,10 @@ absl_cc_library(
absl::core_headers
absl::fast_type_id
absl::flat_hash_map
- absl::raw_logging_internal
absl::random_internal_mock_helpers
absl::random_mocking_access
absl::random_random
+ absl::raw_logging_internal
absl::type_traits
absl::utility
GTest::gmock
@@ -205,10 +205,10 @@ absl_cc_library(
absl::base_internal
absl::config
absl::core_headers
- absl::random_internal_generate_real
absl::random_internal_distribution_caller
absl::random_internal_fast_uniform_bits
absl::random_internal_fastmath
+ absl::random_internal_generate_real
absl::random_internal_iostream_state_saver
absl::random_internal_traits
absl::random_internal_uniform_helper
@@ -220,10 +220,10 @@ absl_cc_library(
absl_cc_library(
NAME
random_seed_gen_exception
- SRCS
- "seed_gen_exception.cc"
HDRS
"seed_gen_exception.h"
+ SRCS
+ "seed_gen_exception.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -236,10 +236,10 @@ absl_cc_library(
absl_cc_library(
NAME
random_seed_sequences
- SRCS
- "seed_sequences.cc"
HDRS
"seed_sequences.h"
+ SRCS
+ "seed_sequences.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -267,9 +267,9 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::random_distributions
- absl::random_random
- absl::random_internal_sequence_urbg
absl::random_internal_pcg_engine
+ absl::random_internal_sequence_urbg
+ absl::random_random
GTest::gmock
GTest::gtest_main
)
@@ -287,12 +287,12 @@ absl_cc_test(
absl::log
absl::numeric_representation
absl::random_distributions
- absl::random_random
absl::random_internal_distribution_test_util
- absl::random_internal_sequence_urbg
absl::random_internal_pcg_engine
- absl::strings
+ absl::random_internal_sequence_urbg
+ absl::random_random
absl::str_format
+ absl::strings
GTest::gmock
GTest::gtest_main
)
@@ -307,11 +307,11 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::int128
absl::random_distributions
+ absl::random_internal_distribution_test_util
absl::random_random
absl::type_traits
- absl::int128
- absl::random_internal_distribution_test_util
GTest::gmock
GTest::gtest_main
)
@@ -349,8 +349,8 @@ absl_cc_test(
absl::random_internal_pcg_engine
absl::random_internal_sequence_urbg
absl::random_random
- absl::strings
absl::str_format
+ absl::strings
GTest::gmock
GTest::gtest_main
)
@@ -386,16 +386,16 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::random_distributions
- absl::random_random
absl::core_headers
absl::flat_hash_map
absl::log
+ absl::random_distributions
absl::random_internal_distribution_test_util
absl::random_internal_pcg_engine
absl::random_internal_sequence_urbg
- absl::strings
+ absl::random_random
absl::str_format
+ absl::strings
GTest::gmock
GTest::gtest_main
)
@@ -418,8 +418,8 @@ absl_cc_test(
absl::random_internal_pcg_engine
absl::random_internal_sequence_urbg
absl::random_random
- absl::strings
absl::str_format
+ absl::strings
GTest::gmock
GTest::gtest_main
)
@@ -441,8 +441,8 @@ absl_cc_test(
absl::random_internal_distribution_test_util
absl::random_internal_sequence_urbg
absl::random_random
- absl::strings
absl::str_format
+ absl::strings
GTest::gmock
GTest::gtest_main
)
@@ -535,9 +535,9 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::random_seed_sequences
absl::random_internal_nonsecure_base
absl::random_random
+ absl::random_seed_sequences
GTest::gmock
GTest::gtest_main
)
@@ -553,10 +553,10 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::config
- absl::type_traits
absl::bits
+ absl::config
absl::int128
+ absl::type_traits
)
# Internal-only target, do not depend on directly.
@@ -571,10 +571,10 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
- absl::utility
absl::fast_type_id
- absl::type_traits
absl::random_mocking_access
+ absl::type_traits
+ absl::utility
)
# Internal-only target, do not depend on directly.
@@ -595,10 +595,10 @@ absl_cc_library(
absl_cc_library(
NAME
random_internal_seed_material
- SRCS
- "internal/seed_material.cc"
HDRS
"internal/seed_material.h"
+ SRCS
+ "internal/seed_material.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -610,6 +610,7 @@ absl_cc_library(
absl::random_internal_fast_uniform_bits
absl::raw_logging_internal
absl::span
+ absl::string_view
absl::strings
)
@@ -617,10 +618,10 @@ absl_cc_library(
absl_cc_library(
NAME
random_internal_entropy_pool
- SRCS
- "internal/entropy_pool.cc"
HDRS
"internal/entropy_pool.h"
+ SRCS
+ "internal/entropy_pool.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -681,8 +682,8 @@ absl_cc_library(
DEPS
absl::inlined_vector
absl::optional
- absl::span
absl::random_internal_seed_material
+ absl::span
absl::type_traits
)
@@ -825,10 +826,10 @@ absl_cc_library(
absl_cc_library(
NAME
random_internal_randen
- SRCS
- "internal/randen.cc"
HDRS
"internal/randen.h"
+ SRCS
+ "internal/randen.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
@@ -843,27 +844,27 @@ absl_cc_library(
absl_cc_library(
NAME
random_internal_randen_slow
- SRCS
- "internal/randen_slow.cc"
HDRS
"internal/randen_slow.h"
+ SRCS
+ "internal/randen_slow.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::random_internal_platform
absl::config
+ absl::random_internal_platform
)
# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
random_internal_randen_hwaes
- SRCS
- "internal/randen_detect.cc"
HDRS
"internal/randen_detect.h"
+ SRCS
+ "internal/randen_detect.cc"
"internal/randen_hwaes.h"
COPTS
${ABSL_DEFAULT_COPTS}
@@ -871,9 +872,9 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::config
absl::random_internal_platform
absl::random_internal_randen_hwaes_impl
- absl::config
)
# Internal-only target, do not depend on directly.
@@ -889,8 +890,8 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::random_internal_platform
absl::config
+ absl::random_internal_platform
)
# Internal-only target, do not depend on directly.
@@ -911,9 +912,10 @@ absl_cc_library(
absl::config
absl::core_headers
absl::raw_logging_internal
- absl::strings
- absl::str_format
absl::span
+ absl::str_format
+ absl::string_view
+ absl::strings
)
# Internal-only target, do not depend on directly.
@@ -1213,12 +1215,12 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::config
absl::random_internal_iostream_state_saver
absl::random_internal_uniform_helper
- absl::config
absl::raw_logging_internal
- absl::strings
absl::string_view
+ absl::strings
TESTONLY
)
@@ -1233,9 +1235,9 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::int128
absl::random_internal_uniform_helper
GTest::gtest_main
- absl::int128
)
# Internal-only target, do not depend on directly.
@@ -1264,8 +1266,8 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::random_internal_wide_multiply
absl::int128
+ absl::random_internal_wide_multiply
GTest::gmock
GTest::gtest_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution.cc b/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution.cc
index c7a72cb2f61..30ad3f0fe8a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution.cc
@@ -2,6 +2,7 @@
// clang-format off
#include "absl/random/gaussian_distribution.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
index 3ba8d9c541a..efd013e65c2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.bazel
@@ -174,6 +174,7 @@ cc_library(
"//absl/base:dynamic_annotations",
"//absl/base:raw_logging_internal",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:optional",
"//absl/types:span",
],
@@ -237,6 +238,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":seed_material",
+ "//absl/base:config",
"//absl/container:inlined_vector",
"//absl/meta:type_traits",
"//absl/types:optional",
@@ -266,6 +268,7 @@ cc_library(
deps = [
":fastmath",
":traits",
+ "//absl/base:config",
"//absl/meta:type_traits",
"//absl/numeric:bits",
],
@@ -278,7 +281,10 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = ["//absl/numeric:bits"],
+ deps = [
+ "//absl/base:config",
+ "//absl/numeric:bits",
+ ],
)
cc_library(
@@ -334,6 +340,7 @@ cc_library(
deps = [
":iostream_state_saver",
":randen",
+ "//absl/base:config",
"//absl/base:endian",
"//absl/meta:type_traits",
],
@@ -459,6 +466,7 @@ cc_library(
"//absl/base:raw_logging_internal",
"//absl/strings",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:span",
],
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.gn
index d0974f95bc7..4985844d9e9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/BUILD.gn
@@ -121,6 +121,7 @@ absl_source_set("salted_seed_seq") {
]
deps = [
":seed_material",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
@@ -150,6 +151,7 @@ absl_source_set("generate_real") {
deps = [
":fastmath",
":traits",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
]
@@ -161,7 +163,10 @@ absl_source_set("fastmath") {
":*",
"//third_party/abseil-cpp/absl/random:*",
]
- deps = [ "//third_party/abseil-cpp/absl/numeric:bits" ]
+ deps = [
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/numeric:bits",
+ ]
}
absl_source_set("wide_multiply") {
@@ -219,6 +224,7 @@ absl_source_set("randen_engine") {
deps = [
":iostream_state_saver",
":randen",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath.h
index 963b7690f1a..8f4f356a110 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath.h
@@ -22,6 +22,7 @@
#include <cmath>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/numeric/bits.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/generate_real.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/generate_real.h
index 6af0455e345..c547df72079 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/generate_real.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/generate_real.h
@@ -23,6 +23,7 @@
#include <limits>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.h
index 619233337c2..75a2f42d638 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.h
@@ -17,6 +17,7 @@
#include <cstddef>
+#include "absl/base/config.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_hwaes.h"
#include "absl/random/internal/randen_slow.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine.h
index a33736eca52..c2a8f54900c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine.h
@@ -26,6 +26,7 @@
#include <ostream>
#include <type_traits>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/iostream_state_saver.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h
index 68296e85ed5..858a90f68a0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h
@@ -25,6 +25,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/container/inlined_vector.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/seed_material.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel
index 5a611ec9f9e..3508b11e0ce 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel
@@ -71,6 +71,7 @@ cc_library(
"//absl/strings",
"//absl/strings:cord",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:optional",
"//absl/types:optional_ref",
"//absl/types:source_location",
@@ -88,6 +89,7 @@ cc_test(
"//absl/strings",
"//absl/strings:cord",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:source_location",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -129,6 +131,7 @@ cc_library(
"//absl/strings",
"//absl/strings:has_ostream_operator",
"//absl/strings:str_format",
+ "//absl/strings:string_view",
"//absl/types:source_location",
"//absl/types:span",
"//absl/types:variant",
@@ -147,6 +150,7 @@ cc_test(
"//absl/base",
"//absl/memory",
"//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:any",
"//absl/types:source_location",
"//absl/types:variant",
@@ -184,6 +188,7 @@ cc_library(
"//absl/strings",
"//absl/strings:cord",
"//absl/strings:internal",
+ "//absl/strings:string_view",
"//absl/strings:stringify_stream",
"//absl/time",
"//absl/types:source_location",
@@ -205,7 +210,7 @@ cc_test(
"//absl/log:flags",
"//absl/log:log_entry",
"//absl/log:log_sink",
- "//absl/strings",
+ "//absl/strings:string_view",
"//absl/types:source_location",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -273,7 +278,7 @@ cc_test(
":status",
":status_matchers",
":statusor",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -290,7 +295,7 @@ cc_test(
":status",
":status_matchers",
":statusor",
- "//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn
index 1b7ba78353b..da5c6f1e284 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn
@@ -41,6 +41,7 @@ absl_source_set("status") {
"//third_party/abseil-cpp/absl/types:source_location",
"//third_party/abseil-cpp/absl/types:span",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("status_test") {
@@ -78,6 +79,7 @@ absl_source_set("statusor") {
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/abseil-cpp/absl/utility",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("statusor_test") {
@@ -127,7 +129,6 @@ absl_test("status_builder_test") {
"//third_party/abseil-cpp/absl/log:flags",
"//third_party/abseil-cpp/absl/log:log_entry",
"//third_party/abseil-cpp/absl/log:log_sink",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:source_location",
]
@@ -173,6 +174,7 @@ absl_source_set("status_matchers") {
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("status_matchers_test") {
@@ -181,7 +183,6 @@ absl_test("status_matchers_test") {
":status",
":status_matchers",
":statusor",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -192,7 +193,6 @@ absl_test("status_matchers_with_unqualified_macros_test") {
":status",
":status_matchers",
":statusor",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/status/CMakeLists.txt
index 90d4baf1bc6..13ff4a6f28e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/status/CMakeLists.txt
@@ -47,6 +47,7 @@ absl_cc_library(
absl::stacktrace
absl::str_format
absl::strerror
+ absl::string_view
absl::strings
absl::symbolize
PUBLIC
@@ -60,9 +61,10 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::status
absl::source_location
+ absl::status
absl::str_format
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -84,9 +86,10 @@ absl_cc_library(
absl::has_ostream_operator
absl::nullability
absl::raw_logging_internal
- absl::status
absl::source_location
+ absl::status
absl::str_format
+ absl::string_view
absl::strings
absl::type_traits
absl::utility
@@ -102,10 +105,11 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::source_location
absl::status
absl::status_matchers
absl::statusor
- absl::source_location
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -128,6 +132,7 @@ absl_cc_library(
absl::source_location
absl::span
absl::status
+ absl::string_view
absl::strings
absl::time
PUBLIC
@@ -143,7 +148,6 @@ absl_cc_test(
DEPS
absl::core_headers
absl::flags
- GTest::gmock_main
absl::log
absl::log_entry
absl::log_flags
@@ -154,11 +158,13 @@ absl_cc_test(
absl::source_location
absl::span
absl::status
- absl::statusor
absl::status_builder
absl::status_matchers
+ absl::statusor
+ absl::string_view
absl::strings
absl::time
+ GTest::gmock_main
)
absl_cc_library(
@@ -228,8 +234,9 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::status
- absl::statusor
absl::status_matchers
+ absl::statusor
+ absl::string_view
GTest::gmock_main
)
@@ -244,7 +251,8 @@ absl_cc_test(
"ABSL_DEFINE_UNQUALIFIED_STATUS_TESTING_MACROS"
DEPS
absl::status
- absl::statusor
absl::status_matchers
+ absl::statusor
+ absl::string_view
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/internal/statusor_internal.h b/deps/v8/third_party/abseil-cpp/absl/status/internal/statusor_internal.h
index b0862339b09..4de4641d18c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/internal/statusor_internal.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/internal/statusor_internal.h
@@ -19,6 +19,7 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status.cc b/deps/v8/third_party/abseil-cpp/absl/status/status.cc
index 80e84791f4b..e9b0eab3f6d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status.cc
@@ -15,6 +15,7 @@
#include <errno.h>
+#include <cstddef>
#include <cstdint>
#include <memory>
#include <ostream>
@@ -30,6 +31,7 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/source_location.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_payload_printer.h b/deps/v8/third_party/abseil-cpp/absl/status/status_payload_printer.h
index 7e2c8c8bbf8..bcf665bd3e6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_payload_printer.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_payload_printer.h
@@ -17,6 +17,7 @@
#include <optional>
#include <string>
+#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/statusor.h b/deps/v8/third_party/abseil-cpp/absl/status/statusor.h
index 3d7f8c48832..e56656ab5e9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/statusor.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/statusor.h
@@ -47,6 +47,7 @@
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
+#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/meta/type_traits.h"
#include "absl/status/internal/statusor_internal.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/statusor_test.cc b/deps/v8/third_party/abseil-cpp/absl/status/statusor_test.cc
index 8a9504909ec..2754d7b969d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/statusor_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/statusor_test.cc
@@ -23,6 +23,7 @@
#include <memory>
#include <ostream>
#include <sstream>
+#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel
index 7f8ca5f090d..450593236c3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -211,6 +211,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -245,7 +246,9 @@ cc_test(
":charset",
":cord",
":str_format",
+ ":string_view",
":strings",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/container:fixed_array",
"//absl/log:check",
@@ -265,7 +268,9 @@ cc_binary(
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
+ "//absl/base:config",
"//absl/base:raw_logging_internal",
"@google_benchmark//:benchmark_main",
],
@@ -315,6 +320,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:core_headers",
"@googletest//:gtest",
@@ -378,6 +384,7 @@ cc_binary(
visibility = ["//visibility:private"],
deps = [
":strings",
+ "//absl/base:config",
"//absl/base:core_headers",
"@google_benchmark//:benchmark_main",
],
@@ -394,6 +401,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":strings",
+ "//absl/base:config",
"//absl/base:core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -424,6 +432,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -517,6 +526,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":charset",
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -549,6 +559,7 @@ cc_library(
"//visibility:private",
],
deps = [
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -573,7 +584,7 @@ cc_test(
deps = [
":cord_internal",
":cord_rep_test_util",
- ":strings",
+ ":string_view",
"//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -590,6 +601,7 @@ cc_test(
deps = [
":cord_internal",
":cord_rep_test_util",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:raw_logging_internal",
@@ -609,6 +621,7 @@ cc_test(
deps = [
":cord_internal",
":cord_rep_test_util",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:raw_logging_internal",
@@ -627,7 +640,7 @@ cc_test(
":cord",
":cord_internal",
":cord_rep_test_util",
- ":strings",
+ ":string_view",
"//absl/base:config",
"//absl/base:raw_logging_internal",
"@googletest//:gtest",
@@ -698,6 +711,7 @@ cc_library(
":cordz_update_tracker",
":internal",
":resize_and_overwrite",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -716,7 +730,6 @@ cc_library(
"//absl/types:compare",
"//absl/types:optional",
"//absl/types:span",
- "@do_not_use_for_gloop_visibility_only//gloop/base:fprint",
],
)
@@ -956,7 +969,7 @@ cc_library(
deps = [
":cord",
":cord_internal",
- ":strings",
+ ":string_view",
"//absl/base:config",
],
)
@@ -969,7 +982,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":cord_internal",
- ":strings",
+ ":string_view",
"//absl/base:config",
"//absl/base:raw_logging_internal",
"//absl/types:span",
@@ -1035,6 +1048,7 @@ cc_test(
":cordz_test_helpers",
":cordz_update_tracker",
":str_format",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -1078,6 +1092,7 @@ cc_test(
":cordz_statistics",
":cordz_test_helpers",
":cordz_update_tracker",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -1094,6 +1109,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:core_headers",
"@googletest//:gtest",
@@ -1138,6 +1154,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1150,6 +1167,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:core_headers",
"//absl/base:dynamic_annotations",
@@ -1170,6 +1188,7 @@ cc_binary(
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:raw_logging_internal",
"@google_benchmark//:benchmark_main",
@@ -1226,6 +1245,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:core_headers",
"//absl/memory",
@@ -1255,6 +1275,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":str_format",
+ ":string_view",
":strings",
"//absl/base:config",
"@googletest//:gtest",
@@ -1271,6 +1292,7 @@ cc_binary(
visibility = ["//visibility:private"],
deps = [
":str_format",
+ ":string_view",
":strings",
"//absl/random",
"//absl/random:distributions",
@@ -1290,6 +1312,7 @@ cc_test(
deps = [
":internal",
":pow10_helper",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/cleanup",
@@ -1310,6 +1333,7 @@ cc_binary(
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"//absl/base:raw_logging_internal",
"//absl/random",
@@ -1325,6 +1349,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
visibility = ["//visibility:private"],
deps = [
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1338,6 +1363,7 @@ cc_test(
deps = [
":pow10_helper",
":str_format",
+ ":string_view",
":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1352,6 +1378,7 @@ cc_test(
],
copts = ABSL_TEST_COPTS,
deps = [
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/log:check",
@@ -1369,6 +1396,7 @@ cc_test(
],
copts = ABSL_TEST_COPTS,
deps = [
+ ":string_view",
":strings",
"//absl/base:config",
"@googletest//:gtest",
@@ -1434,6 +1462,7 @@ cc_library(
visibility = ["//visibility:private"],
deps = [
":internal",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -1458,6 +1487,7 @@ cc_test(
":cord",
":str_format",
":str_format_internal",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -1477,7 +1507,7 @@ cc_test(
deps = [
":str_format",
":str_format_internal",
- ":strings",
+ ":string_view",
"//absl/random",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1506,6 +1536,7 @@ cc_test(
deps = [
":str_format_internal",
":string_view",
+ "//absl/base:config",
"//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1520,6 +1551,7 @@ cc_test(
deps = [
":str_format",
":string_view",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1535,6 +1567,7 @@ cc_test(
deps = [
":str_format",
":str_format_internal",
+ ":string_view",
":strings",
"//absl/base",
"//absl/base:config",
@@ -1557,6 +1590,7 @@ cc_test(
deps = [
":cord",
":str_format_internal",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1596,6 +1630,7 @@ cc_test(
deps = [
":pow10_helper",
":str_format",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1610,6 +1645,7 @@ cc_binary(
visibility = ["//visibility:private"],
deps = [
":str_format",
+ ":string_view",
":strings",
"//absl/base",
],
@@ -1643,6 +1679,7 @@ cc_library(
],
deps = [
":str_format",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/log/internal:container",
@@ -1658,6 +1695,7 @@ cc_test(
deps = [
":generic_printer",
":str_format",
+ ":string_view",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn
index 094e217d9b2..c639fa6199d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -84,6 +84,7 @@ absl_source_set("strings") {
# :string_view.
":string_view",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_source_set("internal") {
@@ -167,6 +168,7 @@ absl_test("escaping_test") {
":str_format",
":string_view",
":strings",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/log:check",
@@ -209,6 +211,7 @@ absl_test("memutil_test") {
]
deps = [
":strings",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
@@ -323,7 +326,6 @@ absl_test("cord_data_edge_test") {
":cord_internal",
":cord_rep_test_util",
":string_view",
- ":strings",
"//third_party/abseil-cpp/absl/base:config",
]
}
@@ -361,7 +363,6 @@ absl_test("cord_rep_btree_reader_test") {
":cord_internal",
":cord_rep_test_util",
":string_view",
- ":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
@@ -432,6 +433,7 @@ absl_source_set("cord") {
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_source_set("cordz_handle") {
@@ -610,7 +612,6 @@ absl_source_set("cord_test_helpers") {
":cord",
":cord_internal",
":string_view",
- ":strings",
"//third_party/abseil-cpp/absl/base:config",
]
}
@@ -622,7 +623,6 @@ absl_source_set("cord_rep_test_util") {
deps = [
":cord_internal",
":string_view",
- ":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/types:span",
@@ -909,7 +909,6 @@ absl_test("str_format_extension_test") {
":str_format",
":str_format_internal",
":string_view",
- ":strings",
"//third_party/abseil-cpp/absl/random",
]
}
@@ -928,6 +927,7 @@ absl_test("str_format_bind_test") {
deps = [
":str_format_internal",
":string_view",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/types:span",
]
}
@@ -937,6 +937,7 @@ absl_test("str_format_checker_test") {
deps = [
":str_format",
":string_view",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
@@ -966,6 +967,7 @@ absl_test("str_format_output_test") {
deps = [
":cord",
":str_format_internal",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
@@ -992,6 +994,7 @@ absl_test("pow10_helper_test") {
deps = [
":pow10_helper",
":str_format",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
@@ -1018,6 +1021,7 @@ absl_source_set("generic_printer") {
"//third_party/abseil-cpp/absl/log/internal:container",
"//third_party/abseil-cpp/absl/meta:requires",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("generic_printer_test") {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
index 3ea24fea105..2d301d816ae 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
@@ -70,10 +70,6 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::string_view
- absl::strings_append_and_overwrite
- absl::strings_internal
- absl::strings_resize_and_overwrite
absl::base
absl::bits
absl::charset
@@ -87,6 +83,10 @@ absl_cc_library(
absl::nullability
absl::raw_logging_internal
absl::source_location
+ absl::string_view
+ absl::strings_append_and_overwrite
+ absl::strings_internal
+ absl::strings_resize_and_overwrite
absl::throw_delegate
absl::type_traits
PUBLIC
@@ -125,8 +125,8 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::string_view
absl::config
+ absl::string_view
)
absl_cc_test(
@@ -137,9 +137,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::str_format
absl::string_view
absl::stringify_stream
- absl::str_format
GTest::gmock_main
)
@@ -190,9 +190,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings_resize_and_overwrite
absl::absl_check
absl::dynamic_annotations
+ absl::strings_resize_and_overwrite
GTest::gmock_main
)
@@ -219,8 +219,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings_resize_and_overwrite
absl::absl_check
+ absl::strings_resize_and_overwrite
GTest::gmock_main
)
@@ -232,8 +232,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::base
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -246,12 +247,13 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::charset
- absl::strings
- absl::str_format
+ absl::check
absl::core_headers
absl::fixed_array
+ absl::str_format
+ absl::string_view
+ absl::strings
GTest::gmock_main
- absl::check
)
absl_cc_test(
@@ -286,8 +288,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::core_headers
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -299,8 +302,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::base
+ absl::strings
GTest::gmock_main
)
@@ -313,8 +316,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::core_headers
+ absl::strings
GTest::gmock_main
)
@@ -326,10 +329,10 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::string_view
- absl::strings_internal
absl::base
absl::core_headers
+ absl::string_view
+ absl::strings_internal
GTest::gmock_main
)
@@ -341,6 +344,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -353,10 +357,10 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::config
absl::core_headers
absl::dynamic_annotations
+ absl::strings
absl::type_traits
GTest::gmock_main
)
@@ -369,8 +373,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::core_headers
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -382,6 +387,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -394,13 +400,14 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
+ absl::btree
absl::core_headers
absl::dynamic_annotations
- absl::btree
absl::flat_hash_map
absl::hash
absl::node_hash_map
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -424,9 +431,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings_internal
absl::base
absl::core_headers
+ absl::strings_internal
absl::type_traits
GTest::gmock_main
)
@@ -439,10 +446,11 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::base
absl::core_headers
absl::memory
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -454,10 +462,11 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
- absl::str_format
absl::config
absl::core_headers
+ absl::str_format
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -478,6 +487,7 @@ absl_cc_test(
absl::pow10_helper
absl::random_distributions
absl::random_random
+ absl::string_view
absl::strings
absl::strings_internal
GTest::gmock_main
@@ -491,8 +501,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::base
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -504,6 +515,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -516,9 +528,10 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
- absl::str_format
absl::pow10_helper
+ absl::str_format
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -533,6 +546,7 @@ absl_cc_test(
DEPS
absl::check
absl::config
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -547,8 +561,9 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::strings
absl::config
+ absl::string_view
+ absl::strings
GTest::gmock_main
)
@@ -593,17 +608,18 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::bits
- absl::strings
absl::config
absl::core_headers
absl::fixed_array
absl::inlined_vector
- absl::numeric_representation
- absl::type_traits
- absl::utility
absl::int128
+ absl::numeric_representation
absl::span
+ absl::string_view
+ absl::strings
absl::strings_internal
+ absl::type_traits
+ absl::utility
)
absl_cc_test(
@@ -619,6 +635,7 @@ absl_cc_test(
absl::core_headers
absl::span
absl::str_format
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -634,7 +651,7 @@ absl_cc_test(
absl::random_random
absl::str_format
absl::str_format_internal
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -692,6 +709,7 @@ absl_cc_test(
absl::span
absl::str_format
absl::str_format_internal
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -704,8 +722,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::str_format_internal
absl::cord
+ absl::str_format_internal
GTest::gmock_main
)
@@ -717,10 +735,10 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::str_format_internal
- absl::string_view
absl::config
absl::core_headers
+ absl::str_format_internal
+ absl::string_view
GTest::gmock_main
)
@@ -789,16 +807,17 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::compare
absl::compressed_tuple
absl::config
absl::container_memory
- absl::compare
absl::core_headers
absl::crc_cord_state
absl::endian
absl::inlined_vector
absl::layout
absl::raw_logging_internal
+ absl::string_view
absl::strings
absl::throw_delegate
absl::type_traits
@@ -870,8 +889,8 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
- absl::core_headers
absl::cordz_update_tracker
+ absl::core_headers
absl::synchronization
)
@@ -903,8 +922,8 @@ absl_cc_test(
absl::cordz_handle
absl::cordz_test_helpers
absl::memory
- absl::random_random
absl::random_distributions
+ absl::random_random
absl::synchronization
absl::time
GTest::gmock_main
@@ -929,10 +948,10 @@ absl_cc_library(
absl::cordz_statistics
absl::cordz_update_tracker
absl::core_headers
- absl::no_destructor
absl::inlined_vector
- absl::span
+ absl::no_destructor
absl::raw_logging_internal
+ absl::span
absl::stacktrace
absl::synchronization
absl::time
@@ -948,11 +967,11 @@ absl_cc_test(
DEPS
absl::config
absl::cord_internal
- absl::cordz_test_helpers
absl::cordz_handle
absl::cordz_info
absl::cordz_statistics
absl::cordz_test_helpers
+ absl::cordz_test_helpers
absl::cordz_update_tracker
absl::span
absl::stacktrace
@@ -1085,6 +1104,7 @@ absl_cc_library(
absl::optional
absl::raw_logging_internal
absl::span
+ absl::string_view
absl::strings
absl::strings_append_and_overwrite
absl::strings_resize_and_overwrite
@@ -1105,7 +1125,7 @@ absl_cc_library(
absl::config
absl::cord_internal
absl::raw_logging_internal
- absl::strings
+ absl::string_view
TESTONLY
)
@@ -1120,7 +1140,7 @@ absl_cc_library(
absl::config
absl::cord
absl::cord_internal
- absl::strings
+ absl::string_view
TESTONLY
PUBLIC
)
@@ -1167,10 +1187,11 @@ absl_cc_test(
absl::function_ref
absl::hash
absl::hash_testing
- absl::no_destructor
absl::log
+ absl::no_destructor
absl::random_random
absl::str_format
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -1188,7 +1209,7 @@ absl_cc_test(
absl::cord_internal
absl::cord_rep_test_util
absl::core_headers
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -1207,6 +1228,7 @@ absl_cc_test(
absl::cord_rep_test_util
absl::core_headers
absl::raw_logging_internal
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -1225,6 +1247,7 @@ absl_cc_test(
absl::cord_rep_test_util
absl::core_headers
absl::raw_logging_internal
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -1243,7 +1266,7 @@ absl_cc_test(
absl::cord_rep_test_util
absl::core_headers
absl::raw_logging_internal
- absl::strings
+ absl::string_view
GTest::gmock_main
)
@@ -1270,19 +1293,20 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::base
+ absl::config
absl::cord
absl::cord_internal
absl::cord_test_helpers
- absl::cordz_test_helpers
absl::cordz_functions
absl::cordz_info
absl::cordz_sample_token
absl::cordz_statistics
+ absl::cordz_test_helpers
absl::cordz_update_tracker
- absl::base
- absl::config
absl::core_headers
absl::raw_logging_internal
+ absl::string_view
absl::strings
GTest::gmock_main
)
@@ -1299,10 +1323,10 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
- absl::strings
- absl::str_format
absl::log_internal_container
absl::requires_internal
+ absl::str_format
+ absl::strings
)
absl_cc_test(
@@ -1321,6 +1345,7 @@ absl_cc_test(
absl::status
absl::statusor
absl::str_format
+ absl::string_view
absl::strings
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord.cc b/deps/v8/third_party/abseil-cpp/absl/strings/cord.cc
index 5827d8974d5..6d9dd10414a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord.cc
@@ -301,8 +301,7 @@ void Cord::InlineRep::UnrefTree() {
// --------------------------------------------------------------------
// Constructors and destructors
-Cord::Cord(absl::string_view src, MethodIdentifier method)
- : contents_(InlineData::kDefaultInit) {
+Cord::Cord(absl::string_view src, MethodIdentifier method) {
const size_t n = src.size();
if (n <= InlineRep::kMaxInline) {
contents_.set_data(src.data(), n);
@@ -313,7 +312,7 @@ Cord::Cord(absl::string_view src, MethodIdentifier method)
}
template <typename T, Cord::EnableIfString<T>>
-Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) {
+Cord::Cord(T&& src) {
if (src.size() <= InlineRep::kMaxInline) {
contents_.set_data(src.data(), src.size());
} else {
@@ -594,7 +593,7 @@ void Cord::PrependArray(absl::string_view src, MethodIdentifier method) {
size_t cur_size = contents_.inline_size();
if (cur_size + src.size() <= InlineRep::kMaxInline) {
// Use embedded storage.
- InlineData data;
+ InlineData data{};
data.set_inline_size(cur_size + src.size());
memcpy(data.as_chars(), src.data(), src.size());
memcpy(data.as_chars() + src.size(), contents_.data(), cur_size);
@@ -623,7 +622,7 @@ void Cord::PrependPrecise(absl::string_view src, MethodIdentifier method) {
assert(src.size() <= cord_internal::kMaxFlatLength);
if (contents_.remaining_inline_capacity() >= src.size()) {
const size_t cur_size = contents_.inline_size();
- InlineData data;
+ InlineData data{};
data.set_inline_size(cur_size + src.size());
memcpy(data.as_chars(), src.data(), src.size());
memcpy(data.as_chars() + src.size(), contents_.data(), cur_size);
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord.h b/deps/v8/third_party/abseil-cpp/absl/strings/cord.h
index fad5d976f86..ef900f8a7a0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord.h
@@ -190,10 +190,12 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Cord {
// Creates a Cord from an existing Cord. Cord is copyable and efficiently
// movable. The moved-from state is valid but unspecified.
- Cord(const Cord& src);
- Cord(Cord&& src) noexcept;
- Cord& operator=(const Cord& x);
- Cord& operator=(Cord&& x) noexcept;
+ // Moves need to be declared since they are otherwise inhibited via the
+ // declaration of the destructor.
+ Cord(const Cord&) = default;
+ Cord(Cord&&) = default;
+ Cord& operator=(const Cord&) = default;
+ Cord& operator=(Cord&&) = default;
// Creates a Cord from a `src` string. This constructor is marked explicit to
// prevent implicit Cord constructions from arguments convertible to an
@@ -920,8 +922,7 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Cord {
static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*));
- constexpr InlineRep() : data_() {}
- explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
+ InlineRep() = default;
InlineRep(const InlineRep& src);
InlineRep(InlineRep&& src);
InlineRep& operator=(const InlineRep& src);
@@ -1181,8 +1182,7 @@ constexpr Cord::InlineRep::InlineRep(absl::string_view sv,
CordRep* absl_nullable rep)
: data_(sv, rep) {}
-inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
- : data_(InlineData::kDefaultInit) {
+inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) {
if (CordRep* tree = src.tree()) {
EmplaceTree(CordRep::Ref(tree), src.data_,
CordzUpdateTracker::kConstructorCord);
@@ -1364,7 +1364,7 @@ inline void Cord::InlineRep::MaybeRemoveEmptyCrcNode() {
ResetToEmpty();
}
-constexpr inline Cord::Cord() noexcept {}
+constexpr inline Cord::Cord() noexcept : contents_() {}
inline Cord::Cord(absl::string_view src)
: Cord(src, CordzUpdateTracker::kConstructorString) {}
@@ -1378,11 +1378,6 @@ constexpr Cord::Cord(strings_internal::StringConstant<T>)
: &cord_internal::ConstInitExternalStorage<
strings_internal::StringConstant<T>>::value) {}
-inline Cord& Cord::operator=(const Cord& x) {
- contents_ = x.contents_;
- return *this;
-}
-
template <typename T, Cord::EnableIfString<T>>
Cord& Cord::operator=(T&& src) {
if (src.size() <= cord_internal::kMaxBytesToCopy) {
@@ -1392,19 +1387,10 @@ Cord& Cord::operator=(T&& src) {
}
}
-inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}
-
-inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}
-
inline void Cord::swap(Cord& other) noexcept {
contents_.Swap(&other.contents_);
}
-inline Cord& Cord::operator=(Cord&& x) noexcept {
- contents_ = std::move(x.contents_);
- return *this;
-}
-
extern template Cord::Cord(std::string&& src);
inline size_t Cord::size() const {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h b/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h
index 103492be1c9..93274293aec 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h
@@ -30,6 +30,7 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/strings/ascii.h"
@@ -179,7 +180,7 @@ bool WebSafeBase64Unescape(absl::string_view src,
// Converts an ASCII hex string into bytes, returning binary data of length
// `from.size()/2`. The input must be valid hexadecimal data, otherwise the
// return value is unspecified.
-ABSL_DEPRECATED("Use the HexStringToBytes() that returns a bool")
+[[deprecated("Use the HexStringToBytes() that returns a bool")]]
std::string HexStringToBytes(absl::string_view from);
// BytesToHexString()
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
index e91e90bd4ef..7ca850d2a5d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc
@@ -20,6 +20,7 @@
#include <iterator>
#include <string>
+#include "absl/base/config.h"
#include "absl/strings/internal/charconv_parse.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc
index 8d9f62d5abb..2661e8bdfd5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_bigint_test.cc
@@ -19,6 +19,7 @@
#include <string>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
index 2766cf3e2e5..5f9df0ae539 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc
@@ -19,6 +19,7 @@
#include <cstdint>
#include <limits>
+#include "absl/base/config.h"
#include "absl/strings/charconv.h"
#include "absl/strings/internal/memutil.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_data_edge_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_data_edge_test.cc
index 58046febbb0..54ec8ff3155 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_data_edge_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_data_edge_test.cc
@@ -16,6 +16,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_test_util.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc
index 79e446181b3..3d1c3240d92 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.cc
@@ -18,6 +18,7 @@
#include <memory>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/internal/cord_rep_btree.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
index cf45907d109..8a7e85fa471 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
@@ -472,9 +472,6 @@ static constexpr cordz_info_t LittleEndianByte(unsigned char value) {
class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData {
public:
- // DefaultInitType forces the use of the default initialization constructor.
- enum DefaultInitType { kDefaultInit };
-
// kNullCordzInfo holds the little endian representation of intptr_t(1)
// This is the 'null' / initial value of 'cordz_info'. The null value
// is specifically big endian 1 as with 64-bit pointers, the last
@@ -488,8 +485,6 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData {
InlineData() = default;
- explicit InlineData(DefaultInitType) noexcept : rep_(kDefaultInit) {}
-
explicit InlineData(CordRep* rep) noexcept : rep_(rep) {
ABSL_ASSERT(rep != nullptr);
}
@@ -657,16 +652,16 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData {
struct Rep {
// See cordz_info_t for forced alignment and size of `cordz_info` details.
struct AsTree {
+ AsTree() = default;
+
explicit constexpr AsTree(absl::cord_internal::CordRep* tree)
- : rep(tree) {}
- cordz_info_t cordz_info = kNullCordzInfo;
+ : cordz_info(kNullCordzInfo), rep(tree) {}
+
+ cordz_info_t cordz_info;
absl::cord_internal::CordRep* rep;
};
- explicit Rep(DefaultInitType) {}
- constexpr Rep() : data{0} {}
- constexpr Rep(const Rep&) = default;
- constexpr Rep& operator=(const Rep&) = default;
+ Rep() = default;
explicit constexpr Rep(CordRep* rep) : as_tree(rep) {}
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc
index 707e5c8effb..d524fff1366 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc
@@ -18,6 +18,7 @@
#include <cstddef>
#include <cstdint>
+#include "absl/base/config.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h
index 1024525d4a7..d59494d70f7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.h
@@ -20,6 +20,7 @@
#include <cstdint>
#include <iostream>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc
index 8b6af152f8e..4f2717f64cf 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc
@@ -18,6 +18,7 @@
#include <cstddef>
#include <utility>
+#include "absl/base/config.h"
#include "absl/container/inlined_vector.h"
#include "absl/functional/function_ref.h"
#include "absl/strings/internal/cord_internal.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h
index cdb06ba17f5..c35b5daa198 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h
@@ -18,6 +18,7 @@
#include <cstddef>
#include <functional>
+#include "absl/base/config.h"
#include "absl/functional/function_ref.h"
#include "absl/strings/internal/cord_internal.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
index 34da171199e..fab6e71199a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
@@ -22,9 +22,11 @@
#include <cstring>
#include <memory>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -111,7 +113,7 @@ struct CordRepFlat : public CordRep {
// Creates a new flat node.
template <size_t max_flat_size, typename... Args>
- static CordRepFlat* NewImpl(size_t len, Args... args ABSL_ATTRIBUTE_UNUSED) {
+ static CordRepFlat* NewImpl(size_t len, Args... args [[maybe_unused]]) {
if (len <= kMinFlatLength) {
len = kMinFlatLength;
} else if (len > max_flat_size - kFlatOverhead) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc
index 4fa8183898c..8e34856d2c6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc
@@ -17,6 +17,7 @@
#include <cassert>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK
#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle_test.cc
index f2deea2b05a..b748a8f162d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_handle_test.cc
@@ -19,6 +19,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/memory/memory.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/notification.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_statistics_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_statistics_test.cc
index 859bb20b360..fbd4b0e0c46 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_statistics_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_statistics_test.cc
@@ -444,7 +444,7 @@ TEST(CordzInfoStatisticsTest, ThreadSafety) {
// Track 0 - 2 cordz infos at a time, providing permutations of 0, 1
// and 2 CordzHandle and CordzInfo queues being active, with plenty of
// 'empty to non empty' transitions.
- InlineData cords[2];
+ InlineData cords[2] = {};
std::minstd_rand gen;
std::uniform_int_distribution<int> coin_toss(0, 1);
std::uniform_int_distribution<int> dice_roll(1, 6);
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc
index 8386b2cf4da..dad228adcba 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc
@@ -22,6 +22,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/memory/memory.h"
#include "absl/random/random.h"
#include "absl/strings/cordz_test_helpers.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping.cc
index 3c206b40beb..6b66e530319 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping.cc
@@ -17,6 +17,7 @@
#include <cstddef>
#include <limits>
+#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h
index 7b18017a089..82e1b5a3583 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h
@@ -19,6 +19,8 @@
#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_
#include <array>
+
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.h
index ed60155ba04..15b0ce3eb9a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.h
@@ -76,6 +76,8 @@
#include <ostream>
#include <utility>
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.cc
index 0bbd8aa1bd1..b54e5b566fb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.cc
@@ -16,6 +16,7 @@
#include <cstdlib>
+#include "absl/base/config.h"
#include "absl/strings/ascii.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.h
index b5911a01cd8..de4dbd1df00 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil.h
@@ -20,6 +20,7 @@
#include <cstddef>
#include <cstring>
+#include "absl/base/config.h"
#include "absl/base/port.h" // disable some warnings on Windows
#include "absl/strings/ascii.h" // for absl::ascii_tolower
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
index a0e5ec08c2a..5ac41ccb427 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc
@@ -19,6 +19,8 @@
#include <ios>
#include <streambuf>
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper.cc
index 42e96c3425d..8f853102358 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper.cc
@@ -16,6 +16,8 @@
#include <cmath>
+#include "absl/base/config.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper_test.cc
index 4e1f34b3dcc..ac3460987d7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/pow10_helper_test.cc
@@ -18,6 +18,7 @@
#include <cstdint>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/strings/str_format.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h
index a2fcab1a790..43f2e0b33a4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h
@@ -23,6 +23,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/strings/resize_and_overwrite.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc
index c4fb200ca4a..580d81829f1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind_test.cc
@@ -19,6 +19,7 @@
#include <limits>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/strings/internal/str_format/arg.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h
index 14e9a237c2d..99755756714 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h
@@ -19,6 +19,7 @@
#include <cstddef>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/const_init.h"
#include "absl/strings/internal/str_format/arg.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc
index 21f1a7f4e61..dff85bebf7f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/checker_test.cc
@@ -16,6 +16,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
index 46b8588045e..fc7d9ba35e6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/convert_test.cc
@@ -37,6 +37,8 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/casts.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/log/absl_check.h"
#include "absl/log/log.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc
index 5b16a862e97..74f9079b527 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc
@@ -21,6 +21,7 @@
#include <cstddef>
#include <string>
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h
index 71100e71425..35eab5f42db 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.h
@@ -15,6 +15,7 @@
#ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_
+#include "absl/base/config.h"
#include "absl/strings/internal/str_format/extension.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc
index 1e61d194bef..f541669778a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc
@@ -20,6 +20,7 @@
#include <cstdio>
#include <cstring>
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.h
index 15e751ab6f0..6afb97af5dc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output.h
@@ -26,6 +26,7 @@
#include <ostream>
#include <string>
+#include "absl/base/config.h"
#include "absl/base/port.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc
index 83c9589d571..ad319e3da5d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/output_test.cc
@@ -20,6 +20,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/strings/cord.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc
index 475d22132d4..35ec143ef7c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc
@@ -28,6 +28,7 @@
#include <unordered_set>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
index b36eac1ced5..c7cc087b6b1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
@@ -41,6 +41,7 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant.h
index d52c3308462..68517a51f62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant.h
@@ -15,6 +15,7 @@
#ifndef ABSL_STRINGS_INTERNAL_STRING_CONSTANT_H_
#define ABSL_STRINGS_INTERNAL_STRING_CONSTANT_H_
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.cc
index 4efe80f8f85..c9f82582045 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.cc
@@ -16,7 +16,9 @@
#include <cstddef>
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h
index b2e75d92856..e4e5f9e8d9a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h
@@ -21,6 +21,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
#include "absl/types/source_location.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/match.h b/deps/v8/third_party/abseil-cpp/absl/strings/match.h
index ce4fe784737..431d4f5fb34 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/match.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/match.h
@@ -35,6 +35,7 @@
#include <cstring>
+#include "absl/base/config.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_join.h b/deps/v8/third_party/abseil-cpp/absl/strings/str_join.h
index dd9f7f44f35..ccd437af9ea 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_join.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_join.h
@@ -55,6 +55,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/internal/str_join_internal.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_replace.h b/deps/v8/third_party/abseil-cpp/absl/strings/str_replace.h
index ac1dcac0948..3af23579378 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_replace.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_replace.h
@@ -45,6 +45,7 @@
#include <vector>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_split.h b/deps/v8/third_party/abseil-cpp/absl/strings/str_split.h
index b72b44634b5..e86b29a344b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_split.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_split.h
@@ -44,6 +44,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/strings/ascii.h"
@@ -467,8 +468,10 @@ using EnableSplitIfString =
// std::set<std::string> a = absl::StrSplit("b,a,c,a,b", ',');
// // a[0] == "a", a[1] == "b", a[2] == "c"
//
-// // `StrSplit()` can be used within a range-based for loop, in which case
-// // each element will be of type `absl::string_view`.
+// // `StrSplit()` can be used within a range-based for-loop, in which case
+// // each element will be of type `absl::string_view`. The elements will
+// // returned in the order in which they appear in the original string
+// // without any other transformation, e.g. no de-duplication is performed.
// std::vector<std::string> v;
// for (const auto sv : absl::StrSplit("a,b,c", ',')) {
// if (sv != "b") v.emplace_back(sv);
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/strip.h b/deps/v8/third_party/abseil-cpp/absl/strings/strip.h
index 55398ffe889..aa225ad2d30 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/strip.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/strip.h
@@ -25,6 +25,7 @@
#include <string>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/strings/ascii.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h b/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h
index accf26ec020..6c62af6d7bf 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h
@@ -78,6 +78,7 @@
#include <type_traits>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/base/port.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
index 57740efa5ef..c63ba865f89 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
@@ -146,6 +146,7 @@ cc_library(
"//absl/debugging:stacktrace",
"//absl/debugging:symbolize",
"//absl/meta:type_traits",
+ "//absl/strings:string_view",
"//absl/time",
] + select({
"//conditions:default": [],
@@ -247,6 +248,7 @@ cc_library(
],
deps = [
":synchronization",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/functional:any_invocable",
],
@@ -368,7 +370,6 @@ cc_test(
deps = [
":per_thread_sem_test_common",
":synchronization",
- "//absl/strings",
"//absl/time",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn
index a2c63e56fcf..529c4968800 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn
@@ -87,6 +87,7 @@ absl_source_set("synchronization") {
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/debugging:symbolize",
"//third_party/abseil-cpp/absl/meta:type_traits",
+ "//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/time",
]
}
@@ -121,6 +122,7 @@ absl_source_set("thread_pool") {
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":synchronization",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/functional:any_invocable",
]
@@ -168,7 +170,6 @@ absl_test("per_thread_sem_test") {
deps = [
":per_thread_sem_test_common",
":synchronization",
- "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/time",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
index 2805000d6e9..3502d11f0d1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
@@ -59,8 +59,8 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::kernel_timeout_internal
absl::config
+ absl::kernel_timeout_internal
absl::random_random
absl::time
GTest::gmock_main
@@ -100,19 +100,20 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::graphcycles_internal
- absl::kernel_timeout_internal
absl::atomic_hook
absl::base
absl::base_internal
absl::config
absl::core_headers
absl::dynamic_annotations
+ absl::graphcycles_internal
+ absl::kernel_timeout_internal
absl::malloc_internal
absl::meta
absl::nullability
absl::raw_logging_internal
absl::stacktrace
+ absl::string_view
absl::symbolize
absl::time
absl::tracing_internal
@@ -186,8 +187,6 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::synchronization
- absl::thread_pool
absl::base
absl::check
absl::config
@@ -195,6 +194,8 @@ absl_cc_test(
absl::log
absl::memory
absl::random_random
+ absl::synchronization
+ absl::thread_pool
absl::time
GTest::gmock_main
)
@@ -239,10 +240,10 @@ absl_cc_library(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::synchronization
absl::base
absl::config
absl::strings
+ absl::synchronization
absl::time
GTest::gmock
TESTONLY
@@ -258,7 +259,6 @@ absl_cc_test(
DEPS
absl::per_thread_sem_test_common
absl::synchronization
- absl::strings
absl::time
GTest::gmock_main
)
@@ -288,7 +288,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::synchronization
- absl::core_headers
absl::check
+ absl::core_headers
+ absl::synchronization
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.h
index d8e754406f4..600ac30331f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.h
@@ -19,6 +19,7 @@
#ifndef ABSL_SYNCHRONIZATION_BARRIER_H_
#define ABSL_SYNCHRONIZATION_BARRIER_H_
+#include "absl/base/config.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.h
index 46c010bb971..ad622ad354a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.h
@@ -22,6 +22,7 @@
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/internal/tracing.h"
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h
index f8bfbe986a9..0e5dd5369f3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h
@@ -25,6 +25,7 @@
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
+#include "absl/base/config.h"
#include "absl/base/internal/thread_identity.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h
index 7d1099efc6e..aa44062a99d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h
@@ -27,6 +27,7 @@
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/internal/thread_identity.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/kernel_timeout.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h
index f87adf635d3..83c8a9e8864 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include "absl/base/config.h"
#include "absl/base/thread_annotations.h"
#include "absl/functional/any_invocable.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc
index 68782564443..d6e2aace10c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc
@@ -782,7 +782,7 @@ void Mutex::EnableDebugLog(const char* name) {
// Since it's not possible to take address of a destructor, we move the
// actual destructor code into the separate Dtor function and force the
// compiler to emit this function even if it's inline by taking its address.
- ABSL_ATTRIBUTE_UNUSED volatile auto dtor = &Mutex::Dtor;
+ [[maybe_unused]] volatile auto dtor = &Mutex::Dtor;
ABSL_ANNOTATE_IGNORE_WRITES_END();
}
@@ -2788,7 +2788,9 @@ void ReleasableMutexLock::Release() {
}
#ifdef ABSL_HAVE_THREAD_SANITIZER
+#pragma GCC visibility push(default)
extern "C" void __tsan_read1(void* addr);
+#pragma GCC visibility pop
#else
#define __tsan_read1(addr) // do nothing if TSan not enabled
#endif
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel
index 073c229d480..eaea38ab32c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel
@@ -58,6 +58,7 @@ cc_library(
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
+ "//absl/base:cycleclock_internal",
"//absl/base:raw_logging_internal",
"//absl/numeric:int128",
"//absl/strings",
@@ -215,6 +216,7 @@ cc_test(
":time",
"//absl/flags:flag",
"//absl/flags:reflection",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn
index 4a10c420138..83c7143805d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn
@@ -25,6 +25,7 @@ absl_source_set("time") {
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/base:cycleclock_internal",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/strings",
@@ -128,5 +129,6 @@ absl_test("flag_test") {
":time",
"//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/flags:reflection",
+ "//third_party/abseil-cpp/absl/strings:string_view",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/time/CMakeLists.txt
index c3ae98c13c9..b141b62d73d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/time/CMakeLists.txt
@@ -77,8 +77,8 @@ absl_cc_library(
"internal/cctz/src/time_zone_posix.h"
"internal/cctz/src/tzfile.h"
"internal/cctz/src/zone_info_source.cc"
- $<$<PLATFORM_ID:Windows>:internal/cctz/src/time_zone_name_win.cc>
- $<$<PLATFORM_ID:Windows>:internal/cctz/src/time_zone_name_win.h>
+ $<$<PLATFORM_ID:Windows,WindowsStore>:internal/cctz/src/time_zone_name_win.cc>
+ $<$<PLATFORM_ID:Windows,WindowsStore>:internal/cctz/src/time_zone_name_win.h>
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
@@ -99,9 +99,9 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::time
absl::config
absl::raw_logging_internal
+ absl::time
absl::time_zone
TESTONLY
)
@@ -119,14 +119,14 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::time_internal_test_util
- absl::time
absl::config
absl::core_headers
absl::hash_testing
absl::random_random
- absl::strings
absl::str_format
+ absl::strings
+ absl::time
+ absl::time_internal_test_util
absl::time_zone
GTest::gmock_main
)
@@ -141,13 +141,13 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::time
absl::config
absl::core_headers
absl::no_destructor
absl::nullability
absl::raw_logging_internal
absl::synchronization
+ absl::time
)
absl_cc_test(
@@ -158,11 +158,11 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::bind_front
absl::clock_interface
- absl::time
absl::config
- absl::bind_front
absl::synchronization
+ absl::time
GTest::gmock_main
)
@@ -177,11 +177,11 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::clock_interface
- absl::time
absl::config
absl::core_headers
absl::nullability
absl::synchronization
+ absl::time
TESTONLY
)
@@ -193,14 +193,14 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::bind_front
absl::clock_interface
- absl::simulated_clock
- absl::time
absl::config
- absl::bind_front
absl::random_random
absl::raw_logging_internal
+ absl::simulated_clock
absl::synchronization
+ absl::time
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/civil_time.cc b/deps/v8/third_party/abseil-cpp/absl/time/civil_time.cc
index eae7e7f48f8..a7042479337 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/civil_time.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/civil_time.cc
@@ -19,7 +19,9 @@
#include <ostream>
#include <string>
+#include "absl/base/config.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
#include "absl/time/time.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/civil_time.h b/deps/v8/third_party/abseil-cpp/absl/time/civil_time.h
index 865a99bf591..6c90659d546 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/civil_time.h
+++ b/deps/v8/third_party/abseil-cpp/absl/time/civil_time.h
@@ -76,6 +76,7 @@
#include "absl/base/config.h"
#include "absl/strings/string_view.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
+#include "absl/time/internal/cctz/include/cctz/civil_time_detail.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/civil_time_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/civil_time_test.cc
index fed0c30b25b..3f03fc1c590 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/civil_time_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/civil_time_test.cc
@@ -16,6 +16,7 @@
#include <cstddef>
#include <iomanip>
+#include <ios>
#include <iterator>
#include <limits>
#include <sstream>
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/clock.cc b/deps/v8/third_party/abseil-cpp/absl/time/clock.cc
index b87611aca8c..d368659e016 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/clock.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/clock.cc
@@ -22,12 +22,15 @@
#include <limits>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/internal/unscaledcycleclock_config.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/base/thread_annotations.h"
+#include "absl/time/time.h"
#ifdef _WIN32
#include <windows.h>
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/clock_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/time/clock_benchmark.cc
index df14ce6ff5d..3f83a5781ec 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/clock_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/clock_benchmark.cc
@@ -11,11 +11,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/time/clock.h"
-
#include <cstdio>
+#include <ctime>
#include "absl/base/internal/cycleclock.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
#include "benchmark/benchmark.h"
#if !defined(_WIN32)
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/duration_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/time/duration_benchmark.cc
index 5a33c65850f..069ae44c438 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/duration_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/duration_benchmark.cc
@@ -16,6 +16,7 @@
#include <cstdint>
#include <ctime>
#include <iterator>
+#include <limits>
#include <string>
#include "absl/base/attributes.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/flag_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/flag_test.cc
index 8f8532b7eb7..59b27dd3b0b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/flag_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/flag_test.cc
@@ -18,6 +18,7 @@
#include "gtest/gtest.h"
#include "absl/flags/reflection.h"
+#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
#include "absl/time/time.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/format.cc b/deps/v8/third_party/abseil-cpp/absl/time/format.cc
index aa2ae2c5493..0794d7d9d0a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/format.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/format.cc
@@ -15,9 +15,12 @@
#include <string.h>
#include <cctype>
+#include <chrono> // NOLINT(build/c++11)
#include <cstdint>
+#include <string>
#include <utility>
+#include "absl/base/config.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/format_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/time/format_benchmark.cc
index 45109faf674..634c371f284 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/format_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/format_benchmark.cc
@@ -15,6 +15,7 @@
#include <iterator>
#include <string>
+#include "absl/time/civil_time.h"
#include "absl/time/internal/test_util.h"
#include "absl/time/time.h"
#include "benchmark/benchmark.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/format_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/format_test.cc
index 38c0e3d89db..0222b6ef249 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/format_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/format_test.cc
@@ -18,6 +18,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/time/civil_time.h"
#include "absl/time/internal/test_util.h"
#include "absl/time/time.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.cc
index 3e2452e9c33..cb7455f326b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.cc
@@ -14,8 +14,11 @@
#include "absl/time/internal/test_util.h"
+#include <string>
+
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/time/time.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.h b/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.h
index 5c4bf1f680e..7a861d80188 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.h
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/test_util.h
@@ -17,6 +17,7 @@
#include <string>
+#include "absl/base/config.h"
#include "absl/time/time.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/simulated_clock_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/simulated_clock_test.cc
index 4618338e61d..d428f578def 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/simulated_clock_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/simulated_clock_test.cc
@@ -17,6 +17,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <optional>
#include <thread> // NOLINT(build/c++11)
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/time.cc b/deps/v8/third_party/abseil-cpp/absl/time/time.cc
index 4be13cf5661..fee9901b884 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/time.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/time.cc
@@ -33,10 +33,15 @@
#include "absl/time/time.h"
+#include <chrono> // NOLINT(build/c++11)
+#include <cstdint>
#include <cstring>
#include <ctime>
#include <limits>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/time.h b/deps/v8/third_party/abseil-cpp/absl/time/time.h
index ea9be32062b..b2bfcb228b0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/time.h
+++ b/deps/v8/third_party/abseil-cpp/absl/time/time.h
@@ -737,9 +737,9 @@ bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error);
// the format specified by `absl::ParseDuration()`.
std::string AbslUnparseFlag(Duration d);
-ABSL_DEPRECATED("Use AbslParseFlag() instead.")
+[[deprecated("Use AbslParseFlag() instead.")]]
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
-ABSL_DEPRECATED("Use AbslUnparseFlag() instead.")
+[[deprecated("Use AbslUnparseFlag() instead.")]]
std::string UnparseFlag(Duration d);
// Time
@@ -824,7 +824,7 @@ class Time {
// `absl::TimeZone`.
//
// Deprecated. Use `absl::TimeZone::CivilInfo`.
- struct ABSL_DEPRECATED("Use `absl::TimeZone::CivilInfo`.") Breakdown {
+ struct [[deprecated("Use `absl::TimeZone::CivilInfo`.")]] Breakdown {
int64_t year; // year (e.g., 2013)
int month; // month of year [1:12]
int day; // day of month [1:31]
@@ -851,7 +851,7 @@ class Time {
//
// Deprecated. Use `absl::TimeZone::At(Time)`.
ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
- ABSL_DEPRECATED("Use `absl::TimeZone::At(Time)`.")
+ [[deprecated("Use `absl::TimeZone::At(Time)`.")]]
Breakdown In(TimeZone tz) const;
ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
@@ -1356,7 +1356,7 @@ ABSL_ATTRIBUTE_PURE_FUNCTION inline Time FromCivil(CivilSecond ct,
// `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`.
//
// Deprecated. Use `absl::TimeZone::TimeInfo`.
-struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion {
+struct [[deprecated("Use `absl::TimeZone::TimeInfo`.")]] TimeConversion {
Time pre; // time calculated using the pre-transition offset
Time trans; // when the civil-time discontinuity occurred
Time post; // time calculated using the post-transition offset
@@ -1391,7 +1391,7 @@ struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion {
//
// Deprecated. Use `absl::TimeZone::At(CivilSecond)`.
ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
-ABSL_DEPRECATED("Use `absl::TimeZone::At(CivilSecond)`.")
+[[deprecated("Use `absl::TimeZone::At(CivilSecond)`.")]]
TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour,
int min, int sec, TimeZone tz);
ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
@@ -1411,7 +1411,7 @@ ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
// Deprecated. Use `absl::FromCivil(CivilSecond, TimeZone)`. Note that the
// behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil
// times. If you care about that see `absl::TimeZone::At(absl::CivilSecond)`.
-ABSL_DEPRECATED("Use `absl::FromCivil(CivilSecond, TimeZone)`.")
+[[deprecated("Use `absl::FromCivil(CivilSecond, TimeZone)`.")]]
inline Time FromDateTime(int64_t year, int mon, int day, int hour, int min,
int sec, TimeZone tz) {
ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/time_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/time/time_benchmark.cc
index db8090a7589..a7f24210cc7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/time_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/time_benchmark.cc
@@ -19,6 +19,7 @@
#include <memory>
#include <string>
+#include "absl/time/civil_time.h"
#include "absl/time/clock.h"
#include "absl/time/internal/test_util.h"
#include "absl/time/time.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/time_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/time_test.cc
index d53198a0acd..0572567fa62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/time_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/time_test.cc
@@ -14,28 +14,20 @@
#include "absl/time/time.h"
-#include "absl/base/config.h"
-
-// For feature testing and determining which headers can be included.
-#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
-#include <version>
-#endif
-
#include <chrono> // NOLINT(build/c++11)
-#ifdef __cpp_lib_three_way_comparison
-#include <compare>
-#endif // __cpp_lib_three_way_comparison
#include <cstdint>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <ios>
#include <limits>
+#include <ratio> // NOLINT(build/c++11)
#include <string>
#include <type_traits>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/hash/hash_testing.h"
#include "absl/numeric/int128.h"
#include "absl/strings/str_format.h"
@@ -43,6 +35,15 @@
#include "absl/time/clock.h"
#include "absl/time/internal/test_util.h"
+// For feature testing and determining which headers can be included.
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#include <version>
+#endif
+
+#ifdef __cpp_lib_three_way_comparison
+#include <compare>
+#endif // __cpp_lib_three_way_comparison
+
#if defined(_MSC_VER)
#include <winsock2.h> // for timeval
#endif
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel
index 7ded8da6b40..f36fc4bc3d0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel
@@ -157,6 +157,7 @@ cc_test(
"//absl/hash:hash_testing",
"//absl/meta:type_traits",
"//absl/strings",
+ "//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -241,6 +242,7 @@ cc_test(
deps = [
":compare",
"//absl/base",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn
index 789f09283b7..950008dd6db 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn
@@ -47,6 +47,7 @@ absl_source_set("span") {
"//third_party/abseil-cpp/absl/hash:weakly_mixed_integer",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
absl_test("span_test") {
@@ -77,6 +78,7 @@ absl_source_set("any_span") {
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
+ check_includes_strict = CHECK_INCLUDES_STRICT_PUBLIC_INCLUDES_PRIVATE
}
# any_span_test is not ported because relies on RTTI
@@ -119,6 +121,7 @@ absl_test("compare_test") {
deps = [
":compare",
"//third_party/abseil-cpp/absl/base",
+ "//third_party/abseil-cpp/absl/base:config",
]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt
index 79a4c19f649..e210314e9e2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt
@@ -61,6 +61,7 @@ absl_cc_test(
absl::hash_testing
absl::raw_logging_internal
absl::span
+ absl::string_view
absl::strings
absl::type_traits
GTest::gmock_main
@@ -95,15 +96,15 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::span
absl::base
absl::config
absl::core_headers
absl::exception_testing
absl::fixed_array
absl::hash
- absl::inlined_vector
absl::hash_testing
+ absl::inlined_vector
+ absl::span
absl::strings
absl::type_traits
GTest::gmock_main
@@ -117,14 +118,14 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
- absl::span
absl::base
absl::config
absl::core_headers
absl::exception_testing
absl::fixed_array
- absl::inlined_vector
absl::hash_testing
+ absl::inlined_vector
+ absl::span
absl::strings
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/any_span_test.cc b/deps/v8/third_party/abseil-cpp/absl/types/any_span_test.cc
index e5960c6aa8a..5d61f6bd89d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/any_span_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/types/any_span_test.cc
@@ -20,6 +20,7 @@
#include <iterator>
#include <memory>
#include <optional>
+#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
@@ -1056,9 +1057,9 @@ TEST(MutableAnySpanTest, NonTruncatingSubspan) {
EXPECT_DEATH(span.subspan(5, 1), "");
EXPECT_DEATH(span.subspan(AnySpan<int>::npos, 0), "");
EXPECT_DEATH(span.subspan(AnySpan<int>::npos, 1), "");
- EXPECT_DEATH(span.subspan(0, 5), "");
- EXPECT_DEATH(span.first(5), "");
- EXPECT_DEATH(span.first(AnySpan<int>::npos), "");
+ EXPECT_DEATH(span.subspan(0, 5), "");
+ EXPECT_DEATH(span.first(5), "");
+ EXPECT_DEATH(span.first(AnySpan<int>::npos), "");
}
#endif
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/compare_test.cc b/deps/v8/third_party/abseil-cpp/absl/types/compare_test.cc
index ae73eca50a3..22276e86706 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/compare_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/types/compare_test.cc
@@ -14,8 +14,12 @@
#include "absl/types/compare.h"
+#include <algorithm>
+#include <functional>
+
#include "gtest/gtest.h"
#include "absl/base/casts.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/source_location.h b/deps/v8/third_party/abseil-cpp/absl/types/source_location.h
index 6e14836d66f..36e2d9e53fc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/source_location.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/source_location.h
@@ -72,7 +72,8 @@ ABSL_NAMESPACE_BEGIN
// C++17-compatible class representing a specific location in the source code of
// a program. Similar to std::source_location, but with a few key differences
// explained above.
-class SourceLocation {
+class
+ SourceLocation {
struct PrivateTag {
private:
explicit PrivateTag() = default;
@@ -110,7 +111,8 @@ class SourceLocation {
// }
static constexpr SourceLocation current(
PrivateTag = PrivateTag{}, std::uint_least32_t line = __builtin_LINE(),
- const char* absl_nonnull file_name = __builtin_FILE()) {
+ const char*
+ absl_nonnull file_name = __builtin_FILE()) {
return SourceLocation(line, file_name);
}
#else
@@ -130,7 +132,8 @@ class SourceLocation {
// The file name of the captured source location, or an unspecified string
// if this information is not available. Guaranteed to never be NULL.
- constexpr const char* absl_nonnull file_name() const noexcept {
+ constexpr const char*
+ absl_nonnull file_name() const noexcept {
return file_name_;
}
@@ -146,8 +149,10 @@ class SourceLocation {
private:
// `file_name` must outlive all copies of the `absl::SourceLocation` object,
// so in practice it should be a string literal.
- constexpr SourceLocation(std::uint_least32_t line,
- const char* absl_nonnull file_name)
+ constexpr SourceLocation(
+ std::uint_least32_t line,
+ const char*
+ absl_nonnull file_name)
: line_(line), file_name_(file_name) {}
// We would use [[maybe_unused]] here, but it doesn't work on all supported
@@ -162,7 +167,8 @@ class SourceLocation {
// type.
std::uint_least32_t line_ = 0;
std::uint_least32_t unused_column_ = 0;
- const char* absl_nonnull file_name_ = "";
+ const char*
+ absl_nonnull file_name_ = "";
};
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/span_test.cc b/deps/v8/third_party/abseil-cpp/absl/types/span_test.cc
index 5a8b82e61a0..57cbb995e39 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/span_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/types/span_test.cc
@@ -14,7 +14,9 @@
#include "absl/types/span.h"
+#include <algorithm>
#include <array>
+#include <cstddef>
#include <initializer_list>
#include <numeric>
#include <stdexcept>
@@ -796,9 +798,9 @@ TEST(IntSpan, NoexceptTest) {
template <int i>
struct ConstexprTester {};
-#define ABSL_TEST_CONSTEXPR(expr) \
- do { \
- ABSL_ATTRIBUTE_UNUSED ConstexprTester<(static_cast<void>(expr), 1)> t; \
+#define ABSL_TEST_CONSTEXPR(expr) \
+ do { \
+ [[maybe_unused]] ConstexprTester<(static_cast<void>(expr), 1)> t; \
} while (0)
struct ContainerWithConstexprMethods {
diff --git a/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py b/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py
index fdbb611b95a..19fd6e71efb 100755
--- a/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py
+++ b/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py
@@ -108,7 +108,7 @@ _ADD_CONTENT = {
'container:hashtablez_sampler_test':
'if (is_win) { sources = [] }',
'container:test_allocator':
- 'deps = [ "//third_party/abseil-cpp/absl/base:config", "//third_party/googletest:gtest" ]',
+ 'deps += [ "//third_party/googletest:gtest" ]',
'flags:config':
'public_configs = [ ":absl_flags_config" ]',
'flags:parse_test':
diff --git a/deps/v8/third_party/abseil-cpp/patches/0001-Undeprecate-deprecated.patch b/deps/v8/third_party/abseil-cpp/patches/0001-Undeprecate-deprecated.patch
index 6f960c51e0c..cae1904208a 100644
--- a/deps/v8/third_party/abseil-cpp/patches/0001-Undeprecate-deprecated.patch
+++ b/deps/v8/third_party/abseil-cpp/patches/0001-Undeprecate-deprecated.patch
@@ -181,3 +181,17 @@ index 60b40c3bd4f3f..9d582702ebd5f 100644
// Historical note: Abseil once provided implementations of these type traits
// for platforms that lacked full support. New code should prefer to use the
+diff --git a/third_party/abseil-cpp/absl/base/attributes.h b/third_party/abseil-cpp/absl/base/attributes.h
+index 72614172586f3..6c788ac1b5d79 100644
+--- a/third_party/abseil-cpp/absl/base/attributes.h
++++ b/third_party/abseil-cpp/absl/base/attributes.h
+@@ -649,8 +649,7 @@
+ #error "ABSL_FALLTHROUGH_INTENDED should not be defined."
+ #endif
+ #define ABSL_FALLTHROUGH_INTENDED \
+- struct [[deprecated( \
+- "Use [[fallthrough]] instead.")]] _absl_fallthrough_intended_macro; \
++ struct _absl_fallthrough_intended_macro; \
+ (void)sizeof(_absl_fallthrough_intended_macro*); \
+ [[fallthrough]]
+
diff --git a/deps/v8/third_party/abseil-cpp/patches/0004-string-view-transitive-includes b/deps/v8/third_party/abseil-cpp/patches/0004-string-view-transitive-includes
index be0537cd4d3..05ba1c1c721 100644
--- a/deps/v8/third_party/abseil-cpp/patches/0004-string-view-transitive-includes
+++ b/deps/v8/third_party/abseil-cpp/patches/0004-string-view-transitive-includes
@@ -1,13 +1,12 @@
TODO: crbug.com/472445608 - Remove when when third_party project would stop relying on these transitive includes.
diff --git a/third_party/abseil-cpp/absl/strings/string_view.h b/third_party/abseil-cpp/absl/strings/string_view.h
-index 9daa1492ec786..4855e5bfdf1f1 100644
+index 97f7729db9f67..4855e5bfdf1f1 100644
--- a/third_party/abseil-cpp/absl/strings/string_view.h
+++ b/third_party/abseil-cpp/absl/strings/string_view.h
-@@ -24,6 +24,8 @@
- #ifndef ABSL_STRINGS_STRING_VIEW_H_
+@@ -25,6 +25,7 @@
#define ABSL_STRINGS_STRING_VIEW_H_
-+#include <algorithm>
+ #include <algorithm>
+#include <string>
#include <string_view>
diff --git a/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def b/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def
index 8cdec919a4f..c22828fe2d0 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@_K0@Z
??$Deallocate@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAV?$allocator@D@__Cr@std@@PEAX_K@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QEAUFindElement@412@U?$pair@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0BI@$07@DtorPolicy@container_internal@absl@@SAAEBU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$07$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
@@ -753,6 +760,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_J_K_K_KG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K11G@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0BI@$07@DtorPolicy@container_internal@absl@@CAAEBU012@XZ
??$ReadCallback@P6A_NPEAUSynchEvent@absl@@@Z@Condition@absl@@AEBAXPEAP6A_NPEAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@AEBAXPEAP6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
@@ -2110,7 +2118,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QEAA@XZ
??0GroupAArch64Impl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
??0GroupPortableImpl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QEAA@PEAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QEAA@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QEAA@PEBE@Z
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
@@ -2119,12 +2126,8 @@ EXPORTS
??0HiRep@Duration@absl@@QEAA@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@XZ
- ??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
- ??0InlineRep@Cord@absl@@QEAA@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QEAA@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QEAA@XZ
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
@@ -2174,8 +2177,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
- ??0Rep@InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QEAA@XZ
??0Rep@StatusBuilder@absl@@QEAA@$$QEAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBU012@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBVStatus@2@@Z
@@ -3212,7 +3213,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ
?Data@CordRepFlat@cord_internal@absl@@QEBAPEBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@PEAPEAUCordRep@cord_internal@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAVLogSink@absl@@@__Cr@std@@PEAPEAVLogSink@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
@@ -3259,8 +3259,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAEAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PEAVSourceLocation@3@_K@Z
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -3341,6 +3339,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPEAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPEAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QEBA_NAEBV12@@Z
?EndsWith@Cord@absl@@QEBA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3552,6 +3551,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQEBQEAXHPEBXP6AXPEBDPEAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAAEBUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPEAX_K@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
@@ -3561,11 +3561,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PEAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA_KXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEBA_KXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -3594,6 +3593,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@AEBA_KXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PEBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QEBA?AV?$Span@QEAX@3@XZ
?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3646,6 +3646,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAEAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPEAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAEAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@AEBAPEAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YA_K_K@Z
?GuaranteedEqual@Condition@absl@@SA_NPEBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAAEBCAEBC@Z
@@ -3713,7 +3714,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QEAAPEAUCordRep@23@PEAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AEAAXH_K0@Z
?InitRep@StatusBuilder@absl@@CAPEAURep@12@AEBVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
@@ -3967,10 +3968,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APEAXW4FlagOp@12@PEBXPEAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4063,8 +4064,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
@@ -4178,6 +4179,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AEAAX_K@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4405,6 +4407,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AEAA?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QEBAEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4495,6 +4498,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAXPEAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AEAAXPEAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
@@ -5521,7 +5525,6 @@ EXPORTS
?front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@AEBAPEAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5599,7 +5602,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QEAAPEAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QEAAPEAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPEAX_KPEAW4ctrl_t@23@11_N1@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5622,7 +5624,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QEBAPEBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA_NXZ
?has_infoz@CommonFields@container_internal@absl@@QEBA_NXZ
@@ -5639,12 +5641,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAAAEAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAAEBUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@AEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?hash_with_seed@StringHash@container_internal@absl@@AEBA_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?height@CordRepBtree@cord_internal@absl@@QEBAHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@CommonFields@container_internal@absl@@QEAAXXZ
@@ -5772,6 +5775,10 @@ EXPORTS
?ok@Status@absl@@QEBA_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QEBA_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QEBAPEBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@AEAU423@@Z
@@ -5906,6 +5913,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QEAAXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXPEAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QEAAXXZ
?set_infoz@CommonFields@container_internal@absl@@QEAAXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg_cxx23.def
index 23eb95d92cc..8caeab8e194 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg_cxx23.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@_K0@Z
??$Deallocate@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAV?$allocator@D@__Cr@std@@PEAX_K@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QEAUFindElement@412@U?$pair@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0BI@$07@DtorPolicy@container_internal@absl@@SAAEBU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$07$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
@@ -753,6 +760,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_J_K_K_KG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K11G@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0BI@$07@DtorPolicy@container_internal@absl@@CAAEBU012@XZ
??$ReadCallback@P6A_NPEAUSynchEvent@absl@@@Z@Condition@absl@@AEBAXPEAP6A_NPEAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@AEBAXPEAP6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
@@ -2123,7 +2131,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QEAA@XZ
??0GroupAArch64Impl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
??0GroupPortableImpl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QEAA@PEAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QEAA@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QEAA@PEBE@Z
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
@@ -2132,12 +2139,8 @@ EXPORTS
??0HiRep@Duration@absl@@QEAA@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@XZ
- ??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
- ??0InlineRep@Cord@absl@@QEAA@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QEAA@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QEAA@XZ
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
@@ -2187,8 +2190,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
- ??0Rep@InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QEAA@XZ
??0Rep@StatusBuilder@absl@@QEAA@$$QEAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBU012@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBVStatus@2@@Z
@@ -3225,7 +3226,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ
?Data@CordRepFlat@cord_internal@absl@@QEBAPEBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@PEAPEAUCordRep@cord_internal@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAVLogSink@absl@@@__Cr@std@@PEAPEAVLogSink@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
@@ -3272,8 +3272,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAEAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PEAVSourceLocation@3@_K@Z
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -3354,6 +3352,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPEAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPEAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QEBA_NAEBV12@@Z
?EndsWith@Cord@absl@@QEBA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3565,6 +3564,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQEBQEAXHPEBXP6AXPEBDPEAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAAEBUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPEAX_K@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
@@ -3574,11 +3574,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PEAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA_KXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEBA_KXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -3607,6 +3606,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@AEBA_KXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PEBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QEBA?AV?$Span@QEAX@3@XZ
?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3659,6 +3659,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAEAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPEAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAEAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@AEBAPEAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YA_K_K@Z
?GuaranteedEqual@Condition@absl@@SA_NPEBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAAEBCAEBC@Z
@@ -3725,7 +3726,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QEAAPEAUCordRep@23@PEAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AEAAXH_K0@Z
?InitRep@StatusBuilder@absl@@CAPEAURep@12@AEBVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
@@ -3979,10 +3980,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APEAXW4FlagOp@12@PEBXPEAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4075,8 +4076,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
@@ -4190,6 +4191,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AEAAX_K@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4417,6 +4419,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AEAA?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QEBAEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4507,6 +4510,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAXPEAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AEAAXPEAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
@@ -5546,7 +5550,6 @@ EXPORTS
?front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@AEBAPEAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5624,7 +5627,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QEAAPEAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QEAAPEAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPEAX_KPEAW4ctrl_t@23@11_N1@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5647,7 +5649,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QEBAPEBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA_NXZ
?has_infoz@CommonFields@container_internal@absl@@QEBA_NXZ
@@ -5664,12 +5666,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAAAEAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAAEBUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@AEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?hash_with_seed@StringHash@container_internal@absl@@AEBA_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?height@CordRepBtree@cord_internal@absl@@QEBAHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@CommonFields@container_internal@absl@@QEAAXXZ
@@ -5797,6 +5800,10 @@ EXPORTS
?ok@Status@absl@@QEBA_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QEBA_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QEBAPEBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@AEAU423@@Z
@@ -5931,6 +5938,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QEAAXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXPEAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QEAAXXZ
?set_infoz@CommonFields@container_internal@absl@@QEAAXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def b/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def
index 50ecaf35082..97e5b964ea7 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PEIAXPEIBX_KV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QEAA@XZ
- ??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QEAAAEAV012@AEBC@Z
??$?6D@LogMessage@log_internal@absl@@QEAAAEAV012@AEBD@Z
@@ -36,6 +35,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AllocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPEAXPEAX_K@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -71,7 +71,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -176,7 +182,6 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
@@ -370,6 +375,7 @@ EXPORTS
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??EChunkIterator@Cord@absl@@QEAAAEAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QEAAAEAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
@@ -559,6 +565,7 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
+ ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@AEBV312@V?$FunctionRef@$$A6AXPEAXPEBX@Z@2@@Z
?CopyCordToSpan@absl@@YA_KAEBVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -574,7 +581,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -598,8 +604,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -793,7 +797,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -850,11 +854,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBA_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPEAV12@PEAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
@@ -972,7 +975,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPEAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QEAAPEBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QEBAPEAV123@AEBVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -992,7 +994,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1066,8 +1068,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1330,6 +1332,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
diff --git a/deps/v8/third_party/abseil-cpp/symbols_arm64_rel_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_arm64_rel_cxx23.def
index 6573f37ce73..e7f19e230c5 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_rel_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_rel_cxx23.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PEIAXPEIBX_KV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QEAA@XZ
- ??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QEAAAEAV012@AEBC@Z
??$?6D@LogMessage@log_internal@absl@@QEAAAEAV012@AEBD@Z
@@ -36,6 +35,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AllocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPEAXPEAX_K@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -71,7 +71,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -176,7 +182,6 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
@@ -370,6 +375,7 @@ EXPORTS
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??EChunkIterator@Cord@absl@@QEAAAEAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QEAAAEAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
@@ -559,6 +565,7 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
+ ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@AEBV312@V?$FunctionRef@$$A6AXPEAXPEBX@Z@2@@Z
?CopyCordToSpan@absl@@YA_KAEBVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -574,7 +581,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -598,8 +604,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -793,7 +797,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -850,11 +854,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBA_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPEAV12@PEAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
@@ -972,7 +975,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPEAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QEAAPEBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QEBAPEAV123@AEBVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -992,7 +994,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1066,8 +1068,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1330,6 +1332,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def b/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def
index a56306b4e41..cd2cb4f8c5d 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@_K0@Z
??$Deallocate@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAV?$allocator@D@__Cr@std@@PEAX_K@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QEAUFindElement@412@U?$pair@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0BI@$07@DtorPolicy@container_internal@absl@@SAAEBU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$07$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
@@ -753,6 +760,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_J_K_K_KG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K11G@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0BI@$07@DtorPolicy@container_internal@absl@@CAAEBU012@XZ
??$ReadCallback@P6A_NPEAUSynchEvent@absl@@@Z@Condition@absl@@AEBAXPEAP6A_NPEAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@AEBAXPEAP6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
@@ -2111,7 +2119,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QEAA@XZ
??0GroupPortableImpl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
??0GroupSse2Impl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QEAA@PEAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QEAA@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QEAA@PEBE@Z
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
@@ -2120,12 +2127,8 @@ EXPORTS
??0HiRep@Duration@absl@@QEAA@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@XZ
- ??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
- ??0InlineRep@Cord@absl@@QEAA@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QEAA@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QEAA@XZ
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
@@ -2175,8 +2178,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
- ??0Rep@InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QEAA@XZ
??0Rep@StatusBuilder@absl@@QEAA@$$QEAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBU012@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBVStatus@2@@Z
@@ -3213,7 +3214,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ
?Data@CordRepFlat@cord_internal@absl@@QEBAPEBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@PEAPEAUCordRep@cord_internal@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAVLogSink@absl@@@__Cr@std@@PEAPEAVLogSink@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
@@ -3260,8 +3260,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAEAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PEAVSourceLocation@3@_K@Z
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -3342,6 +3340,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPEAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPEAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QEBA_NAEBV12@@Z
?EndsWith@Cord@absl@@QEBA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3553,6 +3552,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQEBQEAXHPEBXP6AXPEBDPEAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAAEBUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPEAX_K@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
@@ -3562,11 +3562,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PEAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA_KXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEBA_KXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -3595,6 +3594,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@AEBA_KXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PEBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QEBA?AV?$Span@QEAX@3@XZ
?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3647,6 +3647,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAEAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPEAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAEAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@AEBAPEAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YA_K_K@Z
?GuaranteedEqual@Condition@absl@@SA_NPEBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAAEBCAEBC@Z
@@ -3714,7 +3715,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QEAAPEAUCordRep@23@PEAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AEAAXH_K0@Z
?InitRep@StatusBuilder@absl@@CAPEAURep@12@AEBVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
@@ -3971,10 +3972,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APEAXW4FlagOp@12@PEBXPEAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4067,8 +4068,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
@@ -4182,6 +4183,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AEAAX_K@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4409,6 +4411,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AEAA?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QEBAEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4499,6 +4502,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAXPEAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AEAAXPEAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
@@ -5526,7 +5530,6 @@ EXPORTS
?front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@AEBAPEAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5604,7 +5607,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QEAAPEAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QEAAPEAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPEAX_KPEAW4ctrl_t@23@11_N1@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5627,7 +5629,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QEBAPEBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA_NXZ
?has_infoz@CommonFields@container_internal@absl@@QEBA_NXZ
@@ -5644,12 +5646,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAAAEAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAAEBUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@AEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?hash_with_seed@StringHash@container_internal@absl@@AEBA_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?height@CordRepBtree@cord_internal@absl@@QEBAHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@CommonFields@container_internal@absl@@QEAAXXZ
@@ -5777,6 +5780,10 @@ EXPORTS
?ok@Status@absl@@QEBA_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QEBA_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QEBAPEBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@AEAU423@@Z
@@ -5911,6 +5918,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QEAAXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXPEAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QEAAXXZ
?set_infoz@CommonFields@container_internal@absl@@QEAAXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_dbg_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_x64_dbg_cxx23.def
index 203bba8c770..6680d6630f0 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_dbg_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_dbg_cxx23.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@_K0@Z
??$Deallocate@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAV?$allocator@D@__Cr@std@@PEAX_K@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QEAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QEAUFindElement@412@U?$pair@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPEAPEAVLogSink@1@AEAV?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0BI@$07@DtorPolicy@container_internal@absl@@SAAEBU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$07$00@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
@@ -753,6 +760,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_J_K_K_KG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AEAAPEAUHashtablezInfo@container_internal@2@_J_K11G@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0BI@$07@DtorPolicy@container_internal@absl@@CAAEBU012@XZ
??$ReadCallback@P6A_NPEAUSynchEvent@absl@@@Z@Condition@absl@@AEBAXPEAP6A_NPEAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@AEBAXPEAP6A_NPEBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
@@ -2124,7 +2132,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QEAA@XZ
??0GroupPortableImpl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
??0GroupSse2Impl@container_internal@absl@@QEAA@PEBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QEAA@PEAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QEAA@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QEAA@PEBE@Z
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
@@ -2133,12 +2140,8 @@ EXPORTS
??0HiRep@Duration@absl@@QEAA@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AEAA@XZ
- ??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
- ??0InlineRep@Cord@absl@@QEAA@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QEAA@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QEAA@XZ
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
@@ -2188,8 +2191,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
- ??0Rep@InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QEAA@XZ
??0Rep@StatusBuilder@absl@@QEAA@$$QEAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBU012@@Z
??0Rep@StatusBuilder@absl@@QEAA@AEBVStatus@2@@Z
@@ -3226,7 +3227,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QEAAPEADXZ
?Data@CordRepFlat@cord_internal@absl@@QEBAPEBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@PEAPEAUCordRep@cord_internal@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@PEAVLogSink@absl@@@__Cr@std@@PEAPEAVLogSink@3@_K@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
@@ -3273,8 +3273,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAEAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PEAUPayload@status_internal@3@_K@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAEAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PEAVSourceLocation@3@_K@Z
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -3355,6 +3353,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPEAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPEAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPEAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QEBA_NAEBV12@@Z
?EndsWith@Cord@absl@@QEBA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3566,6 +3565,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAAEAPEAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQEBQEAXHPEBXP6AXPEBDPEAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAAEBUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPEAX_K@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
@@ -3575,11 +3575,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PEAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEBA_KXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEBA_KXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -3608,6 +3607,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YA_KPEBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPEAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@AEBA_KXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PEBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QEBA?AV?$Span@QEAX@3@XZ
?GetPayload@Status@absl@@QEBA?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3660,6 +3660,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAEAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPEAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAEAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@AEBAPEAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YA_K_K@Z
?GuaranteedEqual@Condition@absl@@SA_NPEBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAAEBCAEBC@Z
@@ -3726,7 +3727,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QEAAPEAUCordRep@23@PEAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AEAAXH_K0@Z
?InitRep@StatusBuilder@absl@@CAPEAURep@12@AEBVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
@@ -3983,10 +3984,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APEAXW4FlagOp@12@PEBXPEAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4079,8 +4080,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
@@ -4194,6 +4195,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AEAAX_K@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4421,6 +4423,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AEAA?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QEBAEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QEBAEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4511,6 +4514,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAXPEAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AEAAXPEAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
@@ -5551,7 +5555,6 @@ EXPORTS
?front@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@AEBAPEAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5629,7 +5632,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QEAAPEAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QEAAPEAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPEAX_KPEAW4ctrl_t@23@11_N1@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBAAEBV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5652,7 +5654,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QEBAPEBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHAEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QEBA?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QEBA_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA_NXZ
?has_infoz@CommonFields@container_internal@absl@@QEBA_NXZ
@@ -5669,12 +5671,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAAAEAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAAEBUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@AEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?hash_with_seed@StringHash@container_internal@absl@@AEBA_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?height@CordRepBtree@cord_internal@absl@@QEBAHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAX_K@Z
?increment_size@CommonFields@container_internal@absl@@QEAAXXZ
@@ -5802,6 +5805,10 @@ EXPORTS
?ok@Status@absl@@QEBA_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QEBA_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QEBAPEBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@AEAU423@@Z
@@ -5936,6 +5943,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QEAAXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QEAAXPEAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEAAXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QEAAXXZ
?set_infoz@CommonFields@container_internal@absl@@QEAAXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def b/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def
index 0430b16f860..09e82a47364 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PEIAXPEIBX_KV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QEAA@XZ
- ??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QEAAAEAV012@AEBC@Z
??$?6D@LogMessage@log_internal@absl@@QEAAAEAV012@AEBD@Z
@@ -36,6 +35,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AllocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPEAXPEAX_K@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -71,7 +71,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -176,7 +182,6 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
@@ -195,6 +200,7 @@ EXPORTS
??$__call_func@V<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@@?$__policy_func@$$A6AXAEAVCommandLineFlag@absl@@@Z@__function@__Cr@std@@CAXPEBT__policy_storage@123@AEAVCommandLineFlag@absl@@@Z
??$__do_rehash@$00@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AEAAX_K@Z
??$__do_rehash@$00@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@AEAAX_K@Z
+ ??$__emplace_back_slow_path@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
??$__emplace_back_slow_path@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@AEBU34@@Z
??$__emplace_back_slow_path@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__for_each_segment@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@23@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@23@V123@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z@@__Cr@std@@YAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@01@0V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@01@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@01@00V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@01@@Z@@Z
@@ -212,6 +218,7 @@ EXPORTS
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAH$$QEAVcrc32c_t@6@@Z
??$emplace_back@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX$$QEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$emplace_front@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -368,6 +375,7 @@ EXPORTS
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??EChunkIterator@Cord@absl@@QEAAAEAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QEAAAEAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
@@ -380,7 +388,6 @@ EXPORTS
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
- ??R<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBV723@AEA_K@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@AEBQEAV45@@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV456@@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVLogSink@absl@@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@AEBQEAV45@@Z@QEBA?A?<auto>@@XZ
@@ -572,7 +579,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -596,8 +602,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -791,7 +795,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -848,11 +852,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBA_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPEAV12@PEAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
@@ -970,7 +973,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPEAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QEAAPEBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QEBAPEAV123@AEBVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -990,7 +992,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1064,8 +1066,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1328,6 +1330,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
@@ -1411,7 +1414,6 @@ EXPORTS
?n_sec@impl@detail@cctz@time_internal@absl@@YA?AUfields@2345@_J00000@Z
?name@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?next_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
- ?next_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan.def b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan.def
index b3744ff7aa6..6382393a112 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -70,7 +70,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -161,6 +167,12 @@ EXPORTS
??$Merge@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$NewLeaf@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$NewLeaf@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$ParseFlagImpl@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAH@Z
+ ??$ParseFlagImpl@I@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAI@Z
+ ??$ParseFlagImpl@J@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAJ@Z
+ ??$ParseFlagImpl@K@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAK@Z
+ ??$ParseFlagImpl@_J@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEA_J@Z
+ ??$ParseFlagImpl@_K@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEA_K@Z
??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
@@ -169,15 +181,19 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0LD@D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0LD@$$CBD@Z
- ??$StrCat@_K@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_K@Z
??$StrReplaceAll@V?$initializer_list@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V123@@__Cr@std@@@std@@@absl@@YAHAEBV?$initializer_list@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V123@@__Cr@std@@@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@2@@Z
??$StrSplit@VByAnyChar@absl@@@absl@@YA?AV?$Splitter@VByAnyChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@0@VConvertibleToStringView@20@VByAnyChar@0@@Z
??$StrSplit@VByAnyChar@absl@@USkipEmpty@2@@absl@@YA?AV?$Splitter@VByAnyChar@absl@@USkipEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@0@VConvertibleToStringView@20@VByAnyChar@0@USkipEmpty@0@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@H@strings_internal@absl@@YA?AV123@H@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@H@01@YA?AV234@H@Z@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@I@strings_internal@absl@@YA?AV123@I@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@I@01@YA?AV234@I@Z@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@J@strings_internal@absl@@YA?AV123@J@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@J@01@YA?AV234@J@Z@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@K@strings_internal@absl@@YA?AV123@K@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@K@01@YA?AV234@K@Z@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@_J@strings_internal@absl@@YA?AV123@_J@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@_J@01@YA?AV234@_J@Z@@Z
+ ??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$IntegerToString@_K@strings_internal@absl@@YA?AV123@_K@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$IntegerToString@_K@01@YA?AV234@1@Z@@Z
??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@X@strings_internal@absl@@YA?AV123@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@0V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@UNoFormatter@56@@Z@@strings_internal@absl@@YAXAEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_KV<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@X@01@YA?AV234@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@34@2V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@UNoFormatter@01@@Z@@Z
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
@@ -190,7 +206,6 @@ EXPORTS
??$__construct_at_end@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@__Cr@std@@V123@@?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAAXV?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@12@0_K@Z
??$__do_rehash@$00@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AEAAX_K@Z
??$__do_rehash@$00@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@AEAAX_K@Z
- ??$__emplace_back_assume_capacity@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEBUUnrecognizedFlag@absl@@@Z
??$__emplace_back_slow_path@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
??$__emplace_back_slow_path@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAPEAVCommandLineFlag@absl@@AEBQEAV34@@Z
??$__emplace_back_slow_path@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV345@@Z
@@ -204,10 +219,12 @@ EXPORTS
??$__emplace_back_slow_path@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@$$QEAV312@@Z
??$__emplace_back_slow_path@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__for_each_segment@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@23@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@23@V123@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z@@__Cr@std@@YAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@01@0V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@01@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@01@00V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@01@@Z@@Z
+ ??$__if_likely_else@V<lambda_1>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@AEBV834@AEA_K@Z@V<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@234@QEAAAEAU567@012@Z@@__Cr@std@@YAX_NV<lambda_1>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@01@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@01@AEBV701@AEA_K@Z@V<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@301@QEAAAEAU456@123@Z@@Z
??$__if_likely_else@V<lambda_1>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@56@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z@V<lambda_2>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@234@QEAAAEAU56@01@Z@@__Cr@std@@YAX_NV<lambda_1>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@01@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@45@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@01@@Z@V<lambda_2>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@301@QEAAAEAU45@12@Z@@Z
??$__insert_with_size@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@23@V423@@?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@12@1_J@Z
??$construct_at@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@AEA_KAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@23@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@PEAU123@@__Cr@std@@YAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@01@PEAU201@AEA_KAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@01@AEBUpiecewise_construct_t@01@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@01@$$QEAV?$tuple@$$V@01@@Z
??$construct_at@UPayload@status_internal@absl@@AEBU123@PEAU123@@__Cr@std@@YAPEAUPayload@status_internal@absl@@PEAU234@AEBU234@@Z
+ ??$construct_at@UUnrecognizedFlag@absl@@AEBU12@PEAU12@@__Cr@std@@YAPEAUUnrecognizedFlag@absl@@PEAU23@AEBU23@@Z
??$construct_at@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@AEAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@@23@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@PEAV123@@__Cr@std@@YAPEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@01@PEAV201@AEAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@@01@AEBUpiecewise_construct_t@01@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@01@$$QEAV?$tuple@$$V@01@@Z
??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@12@@Z
??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
@@ -216,10 +233,22 @@ EXPORTS
??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
??$emplace_back@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ??$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
+ ??$emplace_back@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@AEBQEAV34@@Z
+ ??$emplace_back@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV345@@Z
+ ??$emplace_back@AEBQEAVLogSink@absl@@@?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@QEAAAEAPEAVLogSink@1@AEBQEAV21@@Z
+ ??$emplace_back@AEBQEAVLogSink@absl@@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@AEBQEAV34@@Z
+ ??$emplace_back@AEBQEBVCommandLineFlag@absl@@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@AEBQEBV34@@Z
+ ??$emplace_back@AEBQEBVCordzHandle@cord_internal@absl@@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@AEBQEBV345@@Z
+ ??$emplace_back@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@AEBU3456@@Z
+ ??$emplace_back@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@Z
+ ??$emplace_back@AEBVSourceLocation@absl@@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAAEAVSourceLocation@1@AEBV21@@Z
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAH$$QEAVcrc32c_t@6@@Z
??$emplace_back@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX$$QEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@PEBVCommandLineFlag@absl@@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@$$QEAPEBV34@@Z
+ ??$emplace_back@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU3456@@Z
+ ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
+ ??$emplace_back@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@$$QEAV312@@Z
??$emplace_front@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -229,6 +258,7 @@ EXPORTS
??$find_large@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAA?AViterator@012@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$find_or_prepare_insert@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@IEAA?AU?$pair@PEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N@__Cr@std@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
??$find_or_prepare_insert_large@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEAA?AU?$pair@PEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N@__Cr@std@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
+ ??$visit@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@AEAV?$variant@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__Cr@std@@X@__Cr@std@@YA?A_T$$QEAUBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@45@@Z@AEAV?$variant@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@01@@Z
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@XZ
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@_K@Z
@@ -253,6 +283,8 @@ EXPORTS
??0ByString@absl@@QEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0CRC@crc_internal@absl@@IEAA@XZ
??0CheckOpMessageBuilder@log_internal@absl@@QEAA@PEBD@Z
+ ??0ChunkIterator@Cord@absl@@AEAA@PEAUCordRep@cord_internal@2@@Z
+ ??0ChunkIterator@Cord@absl@@AEAA@PEBV12@@Z
??0Condition@absl@@QEAA@P6A_NPEAX@Z0@Z
??0Condition@absl@@QEAA@PEB_N@Z
??0Cord@absl@@AEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@W4MethodIdentifier@CordzUpdateTracker@cord_internal@1@@Z
@@ -305,6 +337,7 @@ EXPORTS
??0uint128@absl@@QEAA@M@Z
??0uint128@absl@@QEAA@N@Z
??0uint128@absl@@QEAA@O@Z
+ ??1?$FixedArray@D$0?0V?$allocator@D@__Cr@std@@@absl@@QEAA@XZ
??1?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -372,11 +405,16 @@ EXPORTS
??6time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAV234@V?$civil_time@Uyear_tag@time_internal@absl@@@detail@cctz@01@@Z
??8StatusRep@status_internal@absl@@QEBA_NAEBV012@@Z
??8container_internal@absl@@YA_NAEBViterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@0@Z
+ ??A?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??A?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@_K@Z
??ACord@absl@@QEBAD_K@Z
??BCord@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??E?$SplitIterator@V?$Splitter@VByAnyChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
+ ??E?$SplitIterator@V?$Splitter@VByAnyChar@absl@@USkipEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
+ ??E?$SplitIterator@V?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA_JV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
@@ -387,8 +425,7 @@ EXPORTS
??R<lambda_1>@?0???$__emplace_unique@AEBQEBUCordRep@cord_internal@absl@@@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBQEBUCordRep@cord_internal@absl@@@Z@QEBA?A?<auto>@@00@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
- ??R<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@QEBA?A?<auto>@@AEAVCommandLineFlag@4@@Z
- ??R?$ConvertToContainer@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV123@@Z
+ ??R<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBV723@AEA_K@Z@QEBA?A?<auto>@@XZ
??R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV123@@Z
??RByCivilTime@Transition@cctz@time_internal@absl@@QEBA_NAEBU1234@0@Z
??RDynValueDeleter@flags_internal@absl@@QEBAXPEAX@Z
@@ -467,7 +504,6 @@ EXPORTS
?Append@Cord@absl@@QEAAXAEBV12@@Z
?Append@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z
- ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QEAAX_KD@Z
?Append@StringifySink@strings_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -562,7 +598,6 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
- ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@AEBV312@V?$FunctionRef@$$A6AXPEAXPEBX@Z@2@@Z
?CopyCordToSpan@absl@@YA_KAEBVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -578,7 +613,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -602,8 +636,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -777,7 +809,6 @@ EXPORTS
?FromUniversal@absl@@YA?AVTime@1@_J@Z
?Generate@RandenHwAes@random_internal@absl@@SAXPEBXPEAX@Z
?Generate@RandenSlow@random_internal@absl@@SAXPEBXPEAX@Z
- ?Get@?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@absl@@AEBA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@XZ
?GetAllFlags@absl@@YA?AV?$flat_hash_map@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@UStringHash@container_internal@5@UStringEq@75@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@23@@1@XZ
?GetAndroidNativeTag@log_internal@absl@@YAPEBDXZ
?GetAppendBuffer@CordRepBtree@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z
@@ -797,7 +828,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -858,12 +889,11 @@ EXPORTS
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
?InitTables@CRC32@crc_internal@absl@@UEAAXXZ
- ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z
?InitWhat@BadStatusOrAccess@absl@@AEBAXXZ
?Initialize@ExponentialBiased@profiling_internal@absl@@AEAAXXZ
?InitializeCordRepExternal@cord_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAUCordRepExternal@12@@Z
@@ -997,7 +1027,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1071,8 +1101,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1335,6 +1365,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
@@ -1382,8 +1413,10 @@ EXPORTS
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_from_to@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K0W4__asan_annotation_type@123@W4__asan_annotation_place@123@@Z
?__erase_to_end@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__maybe_remove_back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA_N_N@Z
?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@AEA_K1@Z
?__relocate_with_pivot@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PEAU4567@@Z
?__relocate_with_pivot@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PEAU4567@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -1399,6 +1432,7 @@ EXPORTS
?__throw_length_error@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@CAXXZ
?adaptive_spin_count_@SpinLock@base_internal@absl@@1U?$atomic@H@__Cr@std@@A
?assert_is_full@iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAXPEBD@Z
+ ?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?combine_contiguous@MixingHashState@hash_internal@absl@@SA?AV123@V123@PEBE_K@Z
?cycle_clock_source_@CycleClock@base_internal@absl@@0U?$atomic@P6A_JXZ@__Cr@std@@A
@@ -1410,6 +1444,7 @@ EXPORTS
?format@detail@cctz@time_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV567@AEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@AEBV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@967@AEBVtime_zone@234@@Z
?from_chars@absl@@YA?AUfrom_chars_result@1@PEBD0AEAMW4chars_format@1@@Z
?from_chars@absl@@YA?AUfrom_chars_result@1@PEBD0AEANW4chars_format@1@@Z
+ ?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?infoz_ptr@CommonFields@container_internal@absl@@QEBA?AVHashtablezInfoHandle@23@XZ
@@ -1426,9 +1461,9 @@ EXPORTS
?n_sec@impl@detail@cctz@time_internal@absl@@YA?AUfields@2345@_J00000@Z
?name@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?next_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
- ?next_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
+ ?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
?push_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEBQEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?push_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX$$QEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan_cxx23.def
index 62ca7bbcfeb..7bed4c6322d 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_asan_cxx23.def
@@ -70,7 +70,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -161,6 +167,12 @@ EXPORTS
??$Merge@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$NewLeaf@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$NewLeaf@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$ParseFlagImpl@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAH@Z
+ ??$ParseFlagImpl@I@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAI@Z
+ ??$ParseFlagImpl@J@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAJ@Z
+ ??$ParseFlagImpl@K@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAK@Z
+ ??$ParseFlagImpl@_J@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEA_J@Z
+ ??$ParseFlagImpl@_K@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEA_K@Z
??$ParseFloat@$09@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
??$ParseFloat@$0BA@@strings_internal@absl@@YA?AUParsedFloat@01@PEBD0W4chars_format@1@@Z
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
@@ -169,7 +181,6 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
@@ -188,7 +199,6 @@ EXPORTS
??$__construct_at_end@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@__Cr@std@@V123@@?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAAXV?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@12@0_K@Z
??$__do_rehash@$00@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AEAAX_K@Z
??$__do_rehash@$00@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@AEAAX_K@Z
- ??$__emplace_back_assume_capacity@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEBUUnrecognizedFlag@absl@@@Z
??$__emplace_back_slow_path@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
??$__emplace_back_slow_path@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAPEAVCommandLineFlag@absl@@AEBQEAV34@@Z
??$__emplace_back_slow_path@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV345@@Z
@@ -202,10 +212,12 @@ EXPORTS
??$__emplace_back_slow_path@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@$$QEAV312@@Z
??$__emplace_back_slow_path@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__for_each_segment@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@23@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@23@V123@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z@@__Cr@std@@YAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@01@0V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@01@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@01@00V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@01@@Z@@Z
+ ??$__if_likely_else@V<lambda_1>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@AEBV834@AEA_K@Z@V<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@234@QEAAAEAU567@012@Z@@__Cr@std@@YAX_NV<lambda_1>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@01@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@01@AEBV701@AEA_K@Z@V<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@301@QEAAAEAU456@123@Z@@Z
??$__if_likely_else@V<lambda_1>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@56@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z@V<lambda_2>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@234@QEAAAEAU56@01@Z@@__Cr@std@@YAX_NV<lambda_1>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@01@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@45@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@01@@Z@V<lambda_2>@?0???$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@301@QEAAAEAU45@12@Z@@Z
??$__insert_with_size@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@23@V423@@?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PEAUraw_view@?1???R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV345@@Z@@12@1_J@Z
??$construct_at@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@AEA_KAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@23@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@PEAU123@@__Cr@std@@YAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@01@PEAU201@AEA_KAEAV?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@01@AEBUpiecewise_construct_t@01@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@01@$$QEAV?$tuple@$$V@01@@Z
??$construct_at@UPayload@status_internal@absl@@AEBU123@PEAU123@@__Cr@std@@YAPEAUPayload@status_internal@absl@@PEAU234@AEBU234@@Z
+ ??$construct_at@UUnrecognizedFlag@absl@@AEBU12@PEAU12@@__Cr@std@@YAPEAUUnrecognizedFlag@absl@@PEAU23@AEBU23@@Z
??$construct_at@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@AEAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@@23@AEBUpiecewise_construct_t@23@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@PEAV123@@__Cr@std@@YAPEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@01@PEAV201@AEAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@__Cr@std@@@01@AEBUpiecewise_construct_t@01@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@01@$$QEAV?$tuple@$$V@01@@Z
??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransition@cctz@time_internal@absl@@@12@@Z
??$emplace@$$V@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PEBUTransitionType@cctz@time_internal@absl@@@12@@Z
@@ -214,10 +226,22 @@ EXPORTS
??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
??$emplace_back@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ??$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
+ ??$emplace_back@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@AEBQEAV34@@Z
+ ??$emplace_back@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV345@@Z
+ ??$emplace_back@AEBQEAVLogSink@absl@@@?$InlinedVector@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@absl@@QEAAAEAPEAVLogSink@1@AEBQEAV21@@Z
+ ??$emplace_back@AEBQEAVLogSink@absl@@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@AEBQEAV34@@Z
+ ??$emplace_back@AEBQEBVCommandLineFlag@absl@@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@AEBQEBV34@@Z
+ ??$emplace_back@AEBQEBVCordzHandle@cord_internal@absl@@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@AEBQEBV345@@Z
+ ??$emplace_back@AEBUTransition@cctz@time_internal@absl@@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@AEBU3456@@Z
+ ??$emplace_back@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@Z
+ ??$emplace_back@AEBVSourceLocation@absl@@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAAEAVSourceLocation@1@AEBV21@@Z
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAH$$QEAVcrc32c_t@6@@Z
??$emplace_back@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX$$QEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@PEBVCommandLineFlag@absl@@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@$$QEAPEBV34@@Z
+ ??$emplace_back@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QEAU3456@@Z
+ ??$emplace_back@UPayload@status_internal@absl@@@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@QEAAAEAUPayload@status_internal@1@$$QEAU231@@Z
+ ??$emplace_back@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@$$QEAV312@@Z
??$emplace_front@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -234,6 +258,7 @@ EXPORTS
??$resize_and_overwrite@V<lambda_1>@?0???$IntegerToString@_J@strings_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_J@Z@@?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@QEAAX_KV<lambda_1>@?0???$IntegerToString@_J@strings_internal@absl@@YA?AV012@_J@Z@@Z
??$resize_and_overwrite@V<lambda_1>@?0???$IntegerToString@_K@strings_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_K@Z@@?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@QEAAX_KV<lambda_1>@?0???$IntegerToString@_K@strings_internal@absl@@YA?AV012@0@Z@@Z
??$resize_and_overwrite@V<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@X@strings_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@56@0V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@UNoFormatter@23@@Z@@?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@QEAAX_KV<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@X@strings_internal@absl@@YA?AV012@V?$__wrap_iter@PEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@1V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@UNoFormatter@45@@Z@@Z
+ ??$visit@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@AEAV?$variant@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__Cr@std@@X@__Cr@std@@YA?A_T$$QEAUBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@45@@Z@AEAV?$variant@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@01@@Z
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@XZ
??0?$BigUnsigned@$03@strings_internal@absl@@QEAA@_K@Z
@@ -258,6 +283,8 @@ EXPORTS
??0ByString@absl@@QEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0CRC@crc_internal@absl@@IEAA@XZ
??0CheckOpMessageBuilder@log_internal@absl@@QEAA@PEBD@Z
+ ??0ChunkIterator@Cord@absl@@AEAA@PEAUCordRep@cord_internal@2@@Z
+ ??0ChunkIterator@Cord@absl@@AEAA@PEBV12@@Z
??0Condition@absl@@QEAA@P6A_NPEAX@Z0@Z
??0Condition@absl@@QEAA@PEB_N@Z
??0Cord@absl@@AEAA@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@W4MethodIdentifier@CordzUpdateTracker@cord_internal@1@@Z
@@ -310,6 +337,7 @@ EXPORTS
??0uint128@absl@@QEAA@M@Z
??0uint128@absl@@QEAA@N@Z
??0uint128@absl@@QEAA@O@Z
+ ??1?$FixedArray@D$0?0V?$allocator@D@__Cr@std@@@absl@@QEAA@XZ
??1?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -377,11 +405,16 @@ EXPORTS
??6time_internal@absl@@YAAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAV234@V?$civil_time@Uyear_tag@time_internal@absl@@@detail@cctz@01@@Z
??8StatusRep@status_internal@absl@@QEBA_NAEBV012@@Z
??8container_internal@absl@@YA_NAEBViterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@0@Z
+ ??A?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??A?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@_K@Z
??ACord@absl@@QEBAD_K@Z
??BCord@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??E?$SplitIterator@V?$Splitter@VByAnyChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
+ ??E?$SplitIterator@V?$Splitter@VByAnyChar@absl@@USkipEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
+ ??E?$SplitIterator@V?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@@strings_internal@absl@@QEAAAEAV012@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA_JV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
@@ -392,8 +425,7 @@ EXPORTS
??R<lambda_1>@?0???$__emplace_unique@AEBQEBUCordRep@cord_internal@absl@@@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBQEBUCordRep@cord_internal@absl@@@Z@QEBA?A?<auto>@@00@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
- ??R<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@QEBA?A?<auto>@@AEAVCommandLineFlag@4@@Z
- ??R?$ConvertToContainer@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@AEBV123@@Z
+ ??R<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBV723@AEA_K@Z@QEBA?A?<auto>@@XZ
??R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QEBA?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@AEBV123@@Z
??RByCivilTime@Transition@cctz@time_internal@absl@@QEBA_NAEBU1234@0@Z
??RDynValueDeleter@flags_internal@absl@@QEBAXPEAX@Z
@@ -472,7 +504,6 @@ EXPORTS
?Append@Cord@absl@@QEAAXAEBV12@@Z
?Append@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?Append@FormatSinkImpl@str_format_internal@absl@@QEAAX_KD@Z
- ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QEAAX_KD@Z
?Append@StringifySink@strings_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -567,7 +598,6 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOAEBVFormatConversionSpecImpl@12@PEAVFormatSinkImpl@12@@Z
- ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA_NAEBUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@AEBV312@V?$FunctionRef@$$A6AXPEAXPEBX@Z@2@@Z
?CopyCordToSpan@absl@@YA_KAEBVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXAEBVCord@1@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -583,7 +613,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -607,8 +636,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -782,7 +809,6 @@ EXPORTS
?FromUniversal@absl@@YA?AVTime@1@_J@Z
?Generate@RandenHwAes@random_internal@absl@@SAXPEBXPEAX@Z
?Generate@RandenSlow@random_internal@absl@@SAXPEBXPEAX@Z
- ?Get@?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@absl@@AEBA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@XZ
?GetAllFlags@absl@@YA?AV?$flat_hash_map@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@UStringHash@container_internal@5@UStringEq@75@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@23@@1@XZ
?GetAndroidNativeTag@log_internal@absl@@YAPEBDXZ
?GetAppendBuffer@CordRepBtree@cord_internal@absl@@QEAA?AV?$Span@D@3@_K@Z
@@ -802,7 +828,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -863,12 +889,11 @@ EXPORTS
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
?InitTables@CRC32@crc_internal@absl@@UEAAXXZ
- ?InitTree@ChunkIterator@Cord@absl@@AEAAXPEAUCordRep@cord_internal@3@@Z
?InitWhat@BadStatusOrAccess@absl@@AEBAXXZ
?Initialize@ExponentialBiased@profiling_internal@absl@@AEAAXXZ
?InitializeCordRepExternal@cord_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAUCordRepExternal@12@@Z
@@ -1002,7 +1027,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1076,8 +1101,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1340,6 +1365,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
@@ -1387,8 +1413,10 @@ EXPORTS
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_from_to@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K0W4__asan_annotation_type@123@W4__asan_annotation_place@123@@Z
?__erase_to_end@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__maybe_remove_back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA_N_N@Z
?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@00@Z
?__move_range@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@00@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@AEA_K1@Z
?__relocate_with_pivot@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PEAU4567@@Z
?__relocate_with_pivot@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PEAU4567@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -1404,6 +1432,7 @@ EXPORTS
?__throw_length_error@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@CAXXZ
?adaptive_spin_count_@SpinLock@base_internal@absl@@1U?$atomic@H@__Cr@std@@A
?assert_is_full@iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AEBAXPEBD@Z
+ ?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?combine_contiguous@MixingHashState@hash_internal@absl@@SA?AV123@V123@PEBE_K@Z
?cycle_clock_source_@CycleClock@base_internal@absl@@0U?$atomic@P6A_JXZ@__Cr@std@@A
@@ -1415,6 +1444,7 @@ EXPORTS
?format@detail@cctz@time_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV567@AEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@AEBV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@967@AEBVtime_zone@234@@Z
?from_chars@absl@@YA?AUfrom_chars_result@1@PEBD0AEAMW4chars_format@1@@Z
?from_chars@absl@@YA?AUfrom_chars_result@1@PEBD0AEANW4chars_format@1@@Z
+ ?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?infoz_ptr@CommonFields@container_internal@absl@@QEBA?AVHashtablezInfoHandle@23@XZ
@@ -1431,9 +1461,9 @@ EXPORTS
?n_sec@impl@detail@cctz@time_internal@absl@@YA?AUfields@2345@_J00000@Z
?name@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?next_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
- ?next_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
+ ?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
?push_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEBQEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?push_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX$$QEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_cxx23.def
index 37d6f8a1d89..6b4c8061d07 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_rel_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_rel_cxx23.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PEIAXPEIBX_KV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QEAA@XZ
- ??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAA@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QEAAAEAV012@AEBC@Z
??$?6D@LogMessage@log_internal@absl@@QEAAAEAV012@AEBD@Z
@@ -36,6 +35,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@_K@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QEAA?AUOpResult@012@_NPEAUCordRep@12@_K@Z
??$AllocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPEAXPEAX_K@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -71,7 +71,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AEAAXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX_KPEAW4ctrl_t@01@11_N1@Z
+ ??$DeallocateBackingArray@$07V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPEAX0_K@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAEAVCommonFields@01@AEBUDtorPolicy@01@P6AXPEAX2_K@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PEAX@Z
@@ -176,7 +182,6 @@ EXPORTS
??$Register@AEB_JAEA_KAEA_KAEA_KAEAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QEAAPEAUHashtablezInfo@container_internal@2@AEB_JAEA_K11AEAG@Z
??$SNPrintF@DHHH@absl@@YAHPEAD_KAEBV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@AEBDAEBH44@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$StrCat@PEBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBQEBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBVAlphaNum@0@0000AEBV123@AEAY0BO@$$CBD1@Z
@@ -194,6 +199,7 @@ EXPORTS
??$__call_func@V<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@@?$__policy_func@$$A6AXAEAVCommandLineFlag@absl@@@Z@__function@__Cr@std@@CAXPEBT__policy_storage@123@AEAVCommandLineFlag@absl@@@Z
??$__do_rehash@$00@?$__hash_table@PEBUCordRep@cord_internal@absl@@U?$hash@PEBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PEBUCordRep@cord_internal@absl@@@56@V?$allocator@PEBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AEAAX_K@Z
??$__do_rehash@$00@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@AEAAX_K@Z
+ ??$__emplace_back_slow_path@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@AEBV612@AEA_K@Z
??$__emplace_back_slow_path@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@AEBU34@@Z
??$__emplace_back_slow_path@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__for_each_segment@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@23@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@23@V123@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z@@__Cr@std@@YAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@01@0V<lambda_1>@?0???$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@$0A@@__copy_impl@01@QEBA?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@01@00V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@01@@Z@@Z
@@ -211,6 +217,7 @@ EXPORTS
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAH$$QEAVcrc32c_t@6@@Z
??$emplace_back@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX$$QEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@W4Source@UnrecognizedFlag@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@$$QEAW4Source@34@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$emplace_front@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAXAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QEAAX$$QEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -368,6 +375,7 @@ EXPORTS
??BStatusBuilder@absl@@QEGBA?AVStatus@1@XZ
??BStatusBuilder@absl@@QEHAA?AVStatus@1@XZ
??Bint128@absl@@QEBANXZ
+ ??EChunkIterator@Cord@absl@@QEAAAEAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QEAAAEAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
@@ -380,7 +388,6 @@ EXPORTS
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__hash_iterator@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PEAX@__Cr@std@@@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
??R<lambda_1>@?0???$__emplace_unique@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@V?$tuple@$$V@23@@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@V?$__map_value_compare@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QEAA?AU?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PEAX@23@_J@__Cr@std@@_N@23@AEBUpiecewise_construct_t@23@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@$$QEAV?$tuple@$$V@23@@Z@QEBA?A?<auto>@@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@012@Z
- ??R<lambda_2>@?0???$emplace_back@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@AEA_K@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@AEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBV723@AEA_K@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVCommandLineFlag@absl@@@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@AEBQEAV45@@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVCordzHandle@cord_internal@absl@@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@AEBQEAV456@@Z@QEBA?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@AEBQEAVLogSink@absl@@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@AEBQEAV45@@Z@QEBA?A?<auto>@@XZ
@@ -572,7 +579,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPEAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@AEBAAEAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX1PEAW4ctrl_t@12@11_N1@Z2@Z
?DecodeFrom@ProtoField@log_internal@absl@@QEAA_NPEAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPEADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -596,8 +602,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AEAAXXZ
?DestroyCordSlow@Cord@absl@@AEAAXXZ
?DestroySlots@container_internal@absl@@YAXAEAVCommonFields@12@_KP6AXPEAX2@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
- ?DestructSoo@container_internal@absl@@YAXAEAVCommonFields@12@_K1P6AXPEAX2@ZP6AX21PEAW4ctrl_t@12@11_N1@Z2@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QEAA?AV?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QEBA_NPEBV123@@Z
@@ -791,7 +795,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPEAUCordRep@cord_internal@2@PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QEBA_K_K@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QEBA_K_K@Z
?GetHashtablezMaxSamples@container_internal@absl@@YA_KXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QEAA?AUGraphId@23@PEAX@Z
@@ -848,11 +852,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@AEBA_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPEAV12@PEAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AEAAXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@N_K@__Cr@std@@V?$allocator@U?$pair@N_K@__Cr@std@@@23@@__Cr@std@@PEAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXAEBV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QEAAX_K0@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QEAAX_K0@Z
?InitRepImpl@StatusBuilder@absl@@CAPEAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QEAAXXZ
@@ -970,7 +973,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPEAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPEAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QEAAPEBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QEBAPEAV123@AEBVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -990,7 +992,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPEAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@AEBAAEAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QEAAXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QEAAXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQEAPEADAEAV?$vector@PEADV?$allocator@PEAD@__Cr@std@@@__Cr@std@@AEAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1064,8 +1066,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@AEBAXPEAX@Z
?ReaderTryLockSlow@Mutex@absl@@AEAA_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QEAA?AVGrowthInfoLowerBound@23@_K@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AEAA?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPEAPEAV123@PEAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPEAV123@PEAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
@@ -1328,6 +1330,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QEBAXXZ
?UnrefTree@InlineRep@Cord@absl@@AEAAXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAEAVCommonFields@12@AEBUDtorPolicy@12@P6AXPEAX2_K@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPEAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UEBAXPEAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QEAAXXZ
@@ -1411,7 +1414,6 @@ EXPORTS
?n_sec@impl@detail@cctz@time_internal@absl@@YA?AUfields@2345@_J00000@Z
?name@time_zone@cctz@time_internal@absl@@QEBA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?next_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
- ?next_weekday@detail@cctz@time_internal@absl@@YA?AV?$civil_time@Uday_tag@detail@cctz@time_internal@absl@@@1234@V51234@W4weekday@1234@@Z
?overflow@Streambuf@OStringStream@strings_internal@absl@@MEAAHH@Z
?parse@detail@cctz@time_internal@absl@@YA_NAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0AEBVtime_zone@234@PEAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PEAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PEAV567@@Z
?prev_transition@time_zone@cctz@time_internal@absl@@QEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@1234@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def b/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def
index 5dc09c0c875..800e14885a4 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@II@Z
??$Deallocate@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAV?$allocator@D@__Cr@std@@PAXI@Z
- ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAXIPAW4ctrl_t@01@II_NI@Z
+ ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAX0I@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QAUFindElement@412@U?$pair@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPAPAVLogSink@1@AAV?$InlinedVector@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPAPAVLogSink@1@AAV?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@ABV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0M@$03@DtorPolicy@container_internal@absl@@SAABU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
@@ -752,6 +759,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_JIIIG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@_JIIIG@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0M@$03@DtorPolicy@container_internal@absl@@CAABU012@XZ
??$ReadCallback@P6A_NPAUSynchEvent@absl@@@Z@Condition@absl@@ABEXPAP6A_NPAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@ABEXPAP6A_NPBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AB_JAAIAAIAAIAAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI11AAG@Z
@@ -2109,7 +2117,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QAE@XZ
??0GroupPortableImpl@container_internal@absl@@QAE@PBW4ctrl_t@12@@Z
??0GroupSse2Impl@container_internal@absl@@QAE@PBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QAE@PAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QAE@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QAE@PBE@Z
??0HashtablezInfo@container_internal@absl@@QAE@XZ
@@ -2118,12 +2125,8 @@ EXPORTS
??0HiRep@Duration@absl@@QAE@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AAE@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AAE@XZ
- ??0InlineData@cord_internal@absl@@QAE@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QAE@XZ
??0InlineRep@Cord@absl@@QAE@$$QAV012@@Z
??0InlineRep@Cord@absl@@QAE@ABV012@@Z
- ??0InlineRep@Cord@absl@@QAE@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QAE@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QAE@XZ
??0KernelTimeout@synchronization_internal@absl@@QAE@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QAE@VTime@2@@Z
@@ -2173,8 +2176,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QAE@XZ
??0Rep@CrcCordState@crc_internal@absl@@QAE@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QAE@XZ
- ??0Rep@InlineData@cord_internal@absl@@QAE@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QAE@XZ
??0Rep@StatusBuilder@absl@@QAE@$$QAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QAE@ABU012@@Z
??0Rep@StatusBuilder@absl@@QAE@ABVStatus@2@@Z
@@ -3211,7 +3212,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QAEPADXZ
?Data@CordRepFlat@cord_internal@absl@@QBEPBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@ABEAAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAXIPAW4ctrl_t@12@II_NI@Z1@Z
?Deallocate@?$MallocAdapter@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@PAPAUCordRep@cord_internal@3@I@Z
?Deallocate@?$MallocAdapter@V?$allocator@PAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@PAVLogSink@absl@@@__Cr@std@@PAPAVLogSink@3@I@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PAUPayload@status_internal@3@I@Z
@@ -3258,8 +3258,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PAUPayload@status_internal@3@I@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PAVSourceLocation@3@I@Z
?DestroySlots@container_internal@absl@@YAXAAVCommonFields@12@IP6AXPAX1@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
- ?DestructSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QAE?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QBE_NPBV123@@Z
@@ -3340,6 +3338,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QBE_NABV12@@Z
?EndsWith@Cord@absl@@QBE_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3551,6 +3550,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEAAPAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEAAPAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQBQAXHPBXP6AXPBDPAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAABUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPAXI@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
@@ -3560,11 +3560,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QBEEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QBEIXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QBEII@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QBEIXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QBEII@Z
?GetHashtablezMaxSamples@container_internal@absl@@YAIXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z
@@ -3593,6 +3592,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@ABEIXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QBE?AV?$Span@QAX@3@XZ
?GetPayload@Status@absl@@QBE?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3645,6 +3645,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@ABEPAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YAII@Z
?GuaranteedEqual@Condition@absl@@SA_NPBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAABCABC@Z
@@ -3712,7 +3713,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@NI@__Cr@std@@V?$allocator@U?$pair@NI@__Cr@std@@@23@@__Cr@std@@PAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QAEPAUCordRep@23@PAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXII@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QAEXII@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AAEXHII@Z
?InitRep@StatusBuilder@absl@@CAPAURep@12@ABVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPAURep@12@VStatus@2@@Z
@@ -3968,10 +3969,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@ABEAAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QAEXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QAEXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QAEXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APAXW4FlagOp@12@PBXPAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4064,8 +4065,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@ABEXPAX@Z
?ReaderTryLockSlow@Mutex@absl@@AAE_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPAPAV123@PAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QAEXXZ
@@ -4179,6 +4180,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AAEXI@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4406,6 +4408,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AAE?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QBEEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QBEEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4496,6 +4499,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AAEXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEXPAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QAEXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@ABUDtorPolicy@12@P6AXPAX2I@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AAEXPAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UBEXPAI@Z
@@ -5523,7 +5527,6 @@ EXPORTS
?front@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEAAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@ABEPAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5601,7 +5604,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QAEPAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QAEPAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPAXIPAW4ctrl_t@23@II_NI@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEABV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5624,7 +5626,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QBEPBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QBE?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QBE_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE_NXZ
?has_infoz@CommonFields@container_internal@absl@@QBE_NXZ
@@ -5641,12 +5643,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AAEAAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@ABEABUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@ABEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?hash_with_seed@StringHash@container_internal@absl@@ABEIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?height@CordRepBtree@cord_internal@absl@@QBEHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXI@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXI@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?increment_size@CommonFields@container_internal@absl@@QAEXI@Z
@@ -5774,6 +5777,10 @@ EXPORTS
?ok@Status@absl@@QBE_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QBE_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MAEHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?parse@detail@cctz@time_internal@absl@@YA_NABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0ABVtime_zone@234@PAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QBEPBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@23@AAU423@@Z
@@ -5908,6 +5915,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QAEXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QAEXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QAEXPAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QAEXXZ
?set_infoz@CommonFields@container_internal@absl@@QAEXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x86_dbg_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_x86_dbg_cxx23.def
index 6f1a9600edc..1195fdc489a 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_dbg_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_dbg_cxx23.def
@@ -459,7 +459,7 @@ EXPORTS
??$CreateDefault@$0A@@CommonFields@container_internal@absl@@SA?AV012@XZ
??$CreateWithCustomLimitImpl@$$V@CordBuffer@absl@@CA?AV01@II@Z
??$Deallocate@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAV?$allocator@D@__Cr@std@@PAXI@Z
- ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAXIPAW4ctrl_t@01@II_NI@Z
+ ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAX0I@Z
??$DecomposePair@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@01@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@01@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePair@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@01@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@Z
@@ -470,6 +470,12 @@ EXPORTS
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@$$QAUEmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@U?$pair@V?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@45@@Z
??$DecomposePairImpl@UFindElement@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@67@@memory_internal@container_internal@absl@@YA?AVconst_iterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@12@$$QAUFindElement@412@U?$pair@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@23@@__Cr@std@@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
@@ -570,6 +576,7 @@ EXPORTS
??$GetDataImpl@V?$InlinedVector@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@absl@@@span_internal@absl@@YAPAPAVLogSink@1@AAV?$InlinedVector@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@1@D@Z
??$GetDataImpl@V?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@@span_internal@absl@@YAPAPAVLogSink@1@AAV?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@D@Z
??$GetFlag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@ABV?$Flag@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@@flags_internal@0@@Z
+ ??$GetTrivialDestructRef@$0M@$03@DtorPolicy@container_internal@absl@@SAABU012@XZ
??$GrowSooTableToNextCapacityAndPrepareInsert@$00$00@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$03$00@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPAXAAVCommonFields@01@ABUPolicyFunctions@01@V?$FunctionRef@$$A6AII@Z@1@_N@Z
@@ -752,6 +759,7 @@ EXPORTS
??$ParseFormatString@UParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@@str_format_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UParsedFormatConsumer@ParsedFormatBase@01@@Z
??$PopDead@_JIIIG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@AAEPAUHashtablezInfo@container_internal@2@_JIIIG@Z
??$Prepend@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
+ ??$R@$0M@$03@DtorPolicy@container_internal@absl@@CAABU012@XZ
??$ReadCallback@P6A_NPAUSynchEvent@absl@@@Z@Condition@absl@@ABEXPAP6A_NPAUSynchEvent@1@@Z@Z
??$ReadCallback@P6A_NPBU?$atomic@_N@__Cr@std@@@Z@Condition@absl@@ABEXPAP6A_NPBU?$atomic@_N@__Cr@std@@@Z@Z
??$Register@AB_JAAIAAIAAIAAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI11AAG@Z
@@ -2122,7 +2130,6 @@ EXPORTS
??0GraphCycles@synchronization_internal@absl@@QAE@XZ
??0GroupPortableImpl@container_internal@absl@@QAE@PBW4ctrl_t@12@@Z
??0GroupSse2Impl@container_internal@absl@@QAE@PBW4ctrl_t@12@@Z
- ??0GrowthInfoAccessor@container_internal@absl@@QAE@PAX@Z
??0GrowthInfoLowerBound@container_internal@absl@@QAE@E@Z
??0HashSetIteratorGenerationInfoDisabled@container_internal@absl@@QAE@PBE@Z
??0HashtablezInfo@container_internal@absl@@QAE@XZ
@@ -2131,12 +2138,8 @@ EXPORTS
??0HiRep@Duration@absl@@QAE@_J@Z
??0Impl@time_zone@cctz@time_internal@absl@@AAE@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??0Impl@time_zone@cctz@time_internal@absl@@AAE@XZ
- ??0InlineData@cord_internal@absl@@QAE@W4DefaultInitType@012@@Z
- ??0InlineData@cord_internal@absl@@QAE@XZ
??0InlineRep@Cord@absl@@QAE@$$QAV012@@Z
??0InlineRep@Cord@absl@@QAE@ABV012@@Z
- ??0InlineRep@Cord@absl@@QAE@W4DefaultInitType@InlineData@cord_internal@2@@Z
- ??0InlineRep@Cord@absl@@QAE@XZ
??0InputValue@UnboundConversion@str_format_internal@absl@@QAE@XZ
??0KernelTimeout@synchronization_internal@absl@@QAE@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QAE@VTime@2@@Z
@@ -2186,8 +2189,6 @@ EXPORTS
??0Rep@CordBuffer@absl@@QAE@XZ
??0Rep@CrcCordState@crc_internal@absl@@QAE@XZ
??0Rep@GraphCycles@synchronization_internal@absl@@QAE@XZ
- ??0Rep@InlineData@cord_internal@absl@@QAE@W4DefaultInitType@123@@Z
- ??0Rep@InlineData@cord_internal@absl@@QAE@XZ
??0Rep@StatusBuilder@absl@@QAE@$$QAVStatus@2@@Z
??0Rep@StatusBuilder@absl@@QAE@ABU012@@Z
??0Rep@StatusBuilder@absl@@QAE@ABVStatus@2@@Z
@@ -3224,7 +3225,6 @@ EXPORTS
?Data@CordRepFlat@cord_internal@absl@@QAEPADXZ
?Data@CordRepFlat@cord_internal@absl@@QBEPBDXZ
?DataGuard@FlagImpl@flags_internal@absl@@ABEAAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAXIPAW4ctrl_t@12@II_NI@Z1@Z
?Deallocate@?$MallocAdapter@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@PAPAUCordRep@cord_internal@3@I@Z
?Deallocate@?$MallocAdapter@V?$allocator@PAVLogSink@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@PAVLogSink@absl@@@__Cr@std@@PAPAVLogSink@3@I@Z
?Deallocate@?$MallocAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PAUPayload@status_internal@3@I@Z
@@ -3271,8 +3271,6 @@ EXPORTS
?DestroyElements@?$DestroyAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@$0A@@inlined_vector_internal@absl@@SAXAAV?$allocator@UPayload@status_internal@absl@@@__Cr@std@@PAUPayload@status_internal@3@I@Z
?DestroyElements@?$DestroyAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@$00@inlined_vector_internal@absl@@SAXAAV?$allocator@VSourceLocation@absl@@@__Cr@std@@PAVSourceLocation@3@I@Z
?DestroySlots@container_internal@absl@@YAXAAVCommonFields@12@IP6AXPAX1@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
- ?DestructSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QAE?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QBE_NPBV123@@Z
@@ -3353,6 +3351,7 @@ EXPORTS
?EncodeVarint@log_internal@absl@@YA_N_KHPAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_KIPAV?$Span@D@2@@Z
?EncodeVarint@log_internal@absl@@YA_N_K_JPAV?$Span@D@2@@Z
+ ?EncodeVarint@log_internal@absl@@YA_N_K_NPAV?$Span@D@2@@Z
?EncodeWaitCycles@SpinLock@base_internal@absl@@KAI_J0@Z
?EndsWith@Cord@absl@@QBE_NABV12@@Z
?EndsWith@Cord@absl@@QBE_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -3564,6 +3563,7 @@ EXPORTS
?GetData@?$AllocationTransaction@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEAAPAUPayload@status_internal@3@XZ
?GetData@?$AllocationTransaction@V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEAAPAVSourceLocation@3@XZ
?GetDebugStackTraceHook@debugging_internal@absl@@YAP6AXQBQAXHPBXP6AXPBDPAX@Z3@ZXZ
+ ?GetDtorPolicy@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAABUDtorPolicy@23@XZ
?GetEntropyFromRandenPool@random_internal@absl@@YAXPAXI@Z
?GetEstimatedFairShareMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
?GetEstimatedMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
@@ -3573,11 +3573,10 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthInfoFromControl@container_internal@absl@@YA?AVGrowthInfoAccessor@12@PAW4ctrl_t@12@@Z
- ?GetGrowthInfoLowerBound@GrowthInfoAccessor@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
+ ?GetGrowthInfoLowerBound@CommonFields@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
?GetGrowthLeft@GrowthInfoLowerBound@container_internal@absl@@QBEEXZ
- ?GetGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QBEIXZ
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QBEII@Z
+ ?GetGrowthLeftLowerBound@CommonFields@container_internal@absl@@QBEIXZ
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QBEII@Z
?GetHashtablezMaxSamples@container_internal@absl@@YAIXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z
@@ -3606,6 +3605,7 @@ EXPORTS
?GetMisspellingHints@flags_internal@absl@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
?GetMorePreciseMemoryUsage@cord_internal@absl@@YAIPBUCordRep@12@@Z
?GetOrCreateCurrentThreadIdentity@synchronization_internal@absl@@YAPAUThreadIdentity@base_internal@2@XZ
+ ?GetOverflowGrowthLeft@CommonFields@container_internal@absl@@ABEIXZ
?GetParentMethod@CordzInfo@cord_internal@absl@@CA?AW4MethodIdentifier@CordzUpdateTracker@23@PBV123@@Z
?GetParentStack@CordzInfo@cord_internal@absl@@QBE?AV?$Span@QAX@3@XZ
?GetPayload@Status@absl@@QBE?AV?$optional@VCord@absl@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@45@@Z
@@ -3658,6 +3658,7 @@ EXPORTS
?GlobalHashtablezSampler@container_internal@absl@@YAAAV?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@2@XZ
?GlobalList@CordzInfo@cord_internal@absl@@CAPAUList@123@XZ
?GlobalRegistry@FlagRegistry@flags_internal@absl@@SAAAV123@XZ
+ ?GrowthInfoOverflowAddress@CommonFields@container_internal@absl@@ABEPAXXZ
?GrowthInfoSizeForCapacity@container_internal@absl@@YAII@Z
?GuaranteedEqual@Condition@absl@@SA_NPBV12@0@Z
?Guard@?$NullGuard@C@log_internal@absl@@SAABCABC@Z
@@ -3724,7 +3725,7 @@ EXPORTS
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@NI@__Cr@std@@V?$allocator@U?$pair@NI@__Cr@std@@@23@@__Cr@std@@PAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFirst@CordRepBtreeNavigator@cord_internal@absl@@QAEPAUCordRep@23@PAVCordRepBtree@23@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXII@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QAEXII@Z
?InitInstance@CordRepBtree@cord_internal@absl@@AAEXHII@Z
?InitRep@StatusBuilder@absl@@CAPAURep@12@ABVStatus@2@@Z
?InitRepImpl@StatusBuilder@absl@@CAPAURep@12@VStatus@2@@Z
@@ -3980,10 +3981,10 @@ EXPORTS
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@ABEAAU?$atomic@_J@__Cr@std@@XZ
?OppositeInfinity@time_internal@absl@@YA?AVDuration@2@V32@@Z
- ?OverwriteControlAsFull@GrowthInfoAccessor@container_internal@absl@@QAEXW4ctrl_t@23@@Z
- ?OverwriteEmptyAsFull@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
- ?OverwriteFullAsDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
+ ?OverwriteControlAsFull@CommonFields@container_internal@absl@@QAEXW4ctrl_t@23@@Z
+ ?OverwriteEmptyAsFull@CommonFields@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsDeleted@CommonFields@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QAEXXZ
?Package@flags_internal@absl@@YA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@@Z
?Parse@flags_internal@absl@@YA_NP6APAXW4FlagOp@12@PBXPAX2@ZV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@2PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@56@@Z
?ParseAbseilFlagsOnly@absl@@YAXHQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
@@ -4076,8 +4077,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@ABEXPAX@Z
?ReaderTryLockSlow@Mutex@absl@@AAE_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPAPAV123@PAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@@Z
?RecordClearedReservation@HashtablezInfoHandle@container_internal@absl@@QAEXXZ
@@ -4191,6 +4192,7 @@ EXPORTS
?SetFlagsHelpMatchSubstr@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetFlagsHelpMode@flags_internal@absl@@YAXW4HelpMode@12@@Z
?SetFlagsUsageConfig@absl@@YAXUFlagsUsageConfig@1@@Z
+ ?SetGrowthInfoOverflow@CommonFields@container_internal@absl@@AAEXI@Z
?SetHashtablezConfigListener@container_internal@absl@@YAXP6AXXZ@Z
?SetHashtablezEnabled@container_internal@absl@@YAX_N@Z
?SetHashtablezEnabledInternal@container_internal@absl@@YAX_N@Z
@@ -4418,6 +4420,7 @@ EXPORTS
?ToOpResult@CordRepBtree@cord_internal@absl@@AAE?AUOpResult@123@_N@Z
?ToPublicSeed@?$HashtableInlineDataImpl@$00@container_internal@absl@@CA_K_K@Z
?ToRawData@?$HashtableCapacityImpl@$00@container_internal@absl@@QBEEXZ
+ ?ToRawData@GrowthInfoLowerBound@container_internal@absl@@QBEEXZ
?ToSinkAlso@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToString@?$BigUnsigned@$03@strings_internal@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
@@ -4508,6 +4511,7 @@ EXPORTS
?UnrefTree@InlineRep@Cord@absl@@AAEXXZ
?Unregister@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEXPAUHashtablezInfo@container_internal@3@@Z
?Unregister@HashtablezInfoHandle@container_internal@absl@@QAEXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@ABUDtorPolicy@12@P6AXPAX2I@Z2@Z
?UnsafeSetCordRep@CordzInfo@cord_internal@absl@@AAEXPAUCordRep@23@@Z
?UnsampleSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UBEXPAI@Z
@@ -5548,7 +5552,6 @@ EXPORTS
?front@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEAAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?front@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?front@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransition@cctz@time_internal@absl@@XZ
- ?full_growth_info_ptr@GrowthInfoAccessor@container_internal@absl@@ABEPAXXZ
?gbswap_16@absl@@YAGG@Z
?gbswap_32@absl@@YAII@Z
?gbswap_64@absl@@YA_K_K@Z
@@ -5626,7 +5629,6 @@ EXPORTS
?get@PlacementImpl@?$NoDestructor@VFlagRegistry@flags_internal@absl@@@absl@@QAEPAVFlagRegistry@flags_internal@3@XZ
?get@PlacementImpl@?$NoDestructor@VMutex@absl@@@absl@@QAEPAVMutex@3@XZ
?get_cordz_mean_interval@cord_internal@absl@@YAHXZ
- ?get_dealloc_backing_array_fn@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@CAP6AXPAXIPAW4ctrl_t@23@II_NI@ZXZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEABV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
?get_deleter@?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@23@XZ
@@ -5649,7 +5651,7 @@ EXPORTS
?get_soo_data@HeapOrSoo@container_internal@absl@@QBEPBXXZ
?get_weekday@detail@cctz@time_internal@absl@@YA?AW4weekday@1234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
?get_yearday@detail@cctz@time_internal@absl@@YAHABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@1234@@Z
- ?growth_info@CommonFields@container_internal@absl@@QBE?AVGrowthInfoAccessor@23@XZ
+ ?growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AVGrowthInfoLowerBound@23@XZ
?has_alt_flag@FormatConversionSpecImpl@str_format_internal@absl@@QBE_NXZ
?has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE_NXZ
?has_infoz@CommonFields@container_internal@absl@@QBE_NXZ
@@ -5666,12 +5668,13 @@ EXPORTS
?hash_function@?$__hash_table@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$__unordered_map_equal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$__unordered_map_hasher@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@U?$hash@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@AAEAAUStringHash@23@XZ
?hash_ref@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@ABEABUStringHash@23@XZ
- ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@ABEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
+ ?hash_with_seed@?$HashImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@hash_internal@absl@@IBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?hash_with_seed@StringHash@container_internal@absl@@ABEIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?height@CordRepBtree@cord_internal@absl@@QBEHXZ
?hour@?$civil_time@Uhour_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?hour@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?hour@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
+ ?increment_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXI@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXI@Z
?increment_size@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?increment_size@CommonFields@container_internal@absl@@QAEXI@Z
@@ -5799,6 +5802,10 @@ EXPORTS
?ok@Status@absl@@QBE_NXZ
?ok@Utf8ForCodePoint@debugging_internal@absl@@QBE_NXZ
?overflow@Streambuf@OStringStream@strings_internal@absl@@MAEHH@Z
+ ?overwrite_control_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXW4ctrl_t@23@@Z
+ ?overwrite_empty_as_full@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
+ ?overwrite_full_as_deleted@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
+ ?overwrite_full_as_empty_in_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?parse@detail@cctz@time_internal@absl@@YA_NABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0ABVtime_zone@234@PAV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@67@PAV?$duration@_JV?$ratio@$00$0DINHOKEMGIAAA@@__Cr@std@@@chrono@67@PAV567@@Z
?parsed_conversion@UntypedFormatSpecImpl@str_format_internal@absl@@QBEPBVParsedFormatBase@23@XZ
?pointer_to@?$pointer_traits@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@SAPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@23@AAU423@@Z
@@ -5933,6 +5940,7 @@ EXPORTS
?set_full_soo@CommonFields@container_internal@absl@@QAEXXZ
?set_generation@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QAEXE@Z
?set_generation_ptr@CommonFieldsGenerationInfoDisabled@container_internal@absl@@QAEXPAE@Z
+ ?set_growth_info_lower_bound@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXVGrowthInfoLowerBound@23@@Z
?set_has_infoz@?$HashtableInlineDataImpl@$00@container_internal@absl@@QAEXXZ
?set_has_infoz@CommonFields@container_internal@absl@@QAEXXZ
?set_infoz@CommonFields@container_internal@absl@@QAEXVHashtablezInfoHandle@23@@Z
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def b/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def
index c1075858c50..21daed61911 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PIAXPIBXIV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QAE@XZ
- ??$?0PAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QAE@PAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QAEAAV012@ABC@Z
??$?6D@LogMessage@log_internal@absl@@QAEAAV012@ABD@Z
@@ -21,6 +20,7 @@ EXPORTS
??$?6_J@LogMessage@log_internal@absl@@QAEAAV012@AB_J@Z
??$?6_K@LogMessage@log_internal@absl@@QAEAAV012@AB_K@Z
??$?6_N@LogMessage@log_internal@absl@@QAEAAV012@AB_N@Z
+ ??$?BV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@XZ
??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
??$?OUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QAPAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QBE?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABUpiecewise_construct_t@56@$$QAV?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
@@ -36,6 +36,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@I@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
??$AllocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPAXPAXI@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -72,7 +73,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AAEXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AAEXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AAEXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAXIPAW4ctrl_t@01@II_NI@Z
+ ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAX0I@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
@@ -178,7 +185,6 @@ EXPORTS
??$SNPrintF@DHHH@absl@@YAHPADIABV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@ABDABH33@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHABVCord@0@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$StrCat@I@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@I@Z
- ??$StrCat@PBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABQBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY0BO@$$CBD1@Z
@@ -218,6 +224,7 @@ EXPORTS
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAH$$QAVcrc32c_t@6@@Z
??$emplace_back@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEX$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEX$$QAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@W4Source@UnrecognizedFlag@absl@@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@$$QAW4Source@34@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$emplace_front@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEXAAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEX$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -373,6 +380,7 @@ EXPORTS
??BCord@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
??BStatusBuilder@absl@@QGBE?AVStatus@1@XZ
??Bint128@absl@@QBENXZ
+ ??EChunkIterator@Cord@absl@@QAEAAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QAEAAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Kabsl@@YA?AVint128@0@V10@0@Z
@@ -392,7 +400,6 @@ EXPORTS
??R<lambda_2>@?0???$emplace_back@PBVCommandLineFlag@absl@@@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCommandLineFlag@absl@@$$QAPBV45@@Z@QBE?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU4567@@Z@QBE?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@$$QAV423@@Z@QBE?A?<auto>@@XZ
- ??R?$ConvertToContainer@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@ABV123@@Z
??R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@ABV123@@Z
??RByCivilTime@Transition@cctz@time_internal@absl@@QBE_NABU1234@0@Z
??RDynValueDeleter@flags_internal@absl@@QBEXPAX@Z
@@ -559,6 +566,7 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
+ ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NABUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAAVCommonFields@12@ABUPolicyFunctions@12@ABV312@V?$FunctionRef@$$A6AXPAXPBX@Z@2@@Z
?CopyCordToSpan@absl@@YAIABVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXABVCord@1@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -574,7 +582,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@ABEAAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAXIPAW4ctrl_t@12@II_NI@Z1@Z
?DecodeFrom@ProtoField@log_internal@absl@@QAE_NPAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -598,8 +605,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AAEXXZ
?DestroyCordSlow@Cord@absl@@AAEXXZ
?DestroySlots@container_internal@absl@@YAXAAVCommonFields@12@IP6AXPAX1@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
- ?DestructSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QAE?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QBE_NPBV123@@Z
@@ -793,7 +798,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QBEII@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QBEII@Z
?GetHashtablezMaxSamples@container_internal@absl@@YAIXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z
@@ -850,11 +855,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@ABE_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPAV12@PAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AAEXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@NI@__Cr@std@@V?$allocator@U?$pair@NI@__Cr@std@@@23@@__Cr@std@@PAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXII@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QAEXII@Z
?InitRepImpl@StatusBuilder@absl@@CAPAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QAEXXZ
@@ -972,7 +976,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QAEPBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QBEPAV123@ABVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
@@ -993,7 +996,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@ABEAAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QAEXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1067,8 +1070,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@ABEXPAX@Z
?ReaderTryLockSlow@Mutex@absl@@AAE_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPAPAV123@PAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
@@ -1333,6 +1336,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QBEXXZ
?UnrefTree@InlineRep@Cord@absl@@AAEXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@ABUDtorPolicy@12@P6AXPAX2I@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UBEXPAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QAEXXZ
diff --git a/deps/v8/third_party/abseil-cpp/symbols_x86_rel_cxx23.def b/deps/v8/third_party/abseil-cpp/symbols_x86_rel_cxx23.def
index 39999d36bfe..f944dd5b7d4 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_rel_cxx23.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_rel_cxx23.def
@@ -1,7 +1,6 @@
EXPORTS
?$TSS0@?1??CrcAndCopy@CrcMemcpy@crc_internal@absl@@SA?AVcrc32c_t@4@PIAXPIBXIV54@_N@Z@4HA
??$?0$$V$0A@@?$NoDestructor@V?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@@absl@@QAE@XZ
- ??$?0PAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QAE@PAI0@Z
??$?0V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAE@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?6C@LogMessage@log_internal@absl@@QAEAAV012@ABC@Z
??$?6D@LogMessage@log_internal@absl@@QAEAAV012@ABD@Z
@@ -21,6 +20,7 @@ EXPORTS
??$?6_J@LogMessage@log_internal@absl@@QAEAAV012@AB_J@Z
??$?6_K@LogMessage@log_internal@absl@@QAEAAV012@AB_K@Z
??$?6_N@LogMessage@log_internal@absl@@QAEAAV012@AB_N@Z
+ ??$?BV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@XZ
??$?MUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
??$?OUsecond_tag@detail@cctz@time_internal@absl@@U01234@@detail@cctz@time_internal@absl@@YA_NABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@0@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QAPAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QBE?AU?$pair@Viterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@_N@__Cr@std@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABUpiecewise_construct_t@56@$$QAV?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
@@ -36,6 +36,7 @@ EXPORTS
??$AddData@$00@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@AAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V345@I@Z
??$AddData@$0A@@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
+ ??$AddEdge@$00@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
??$AddEdge@$0A@@CordRepBtree@cord_internal@absl@@QAE?AUOpResult@012@_NPAUCordRep@12@I@Z
??$AllocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAPAXPAXI@Z
??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -72,7 +73,13 @@ EXPORTS
??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AAEXV?$basic_string_view@_WU?$char_traits@_W@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$00@LogMessage@log_internal@absl@@AAEXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$CopyToEncodedBufferWithStructuredProtoField@$0A@@LogMessage@log_internal@absl@@AAEXUStructuredProtoField@12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAXIPAW4ctrl_t@01@II_NI@Z
+ ??$DeallocateBackingArray@$03V?$allocator@D@__Cr@std@@@container_internal@absl@@YAXPAX0I@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z2@Z
+ ??$Destruct@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUDtorPolicy@01@P6AXPAX2I@Z@Z
??$Dispatch@C@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@D@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
??$Dispatch@E@FormatArgImpl@str_format_internal@absl@@CA_NTData@012@VFormatConversionSpecImpl@12@PAX@Z
@@ -178,7 +185,6 @@ EXPORTS
??$SNPrintF@DHHH@absl@@YAHPADIABV?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@0@ABDABH33@Z
??$SharedCompareImpl@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YAHABVCord@0@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$StrCat@I@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@I@Z
- ??$StrCat@PBD@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABQBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY02D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY02$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY03D@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY03$$CBD@Z
??$StrCat@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$$BY0BO@DV123@@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABVAlphaNum@0@0000ABV123@AAY0BO@$$CBD1@Z
@@ -217,6 +223,7 @@ EXPORTS
??$emplace_back@HVcrc32c_t@absl@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAH$$QAVcrc32c_t@6@@Z
??$emplace_back@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEX$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_back@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEX$$QAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
+ ??$emplace_back@W4Source@UnrecognizedFlag@absl@@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@$$QAW4Source@34@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$emplace_front@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEXAAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??$emplace_front@AAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??$emplace_front@PAPBVImpl@time_zone@cctz@time_internal@absl@@@?$__split_buffer@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@78@@__Cr@std@@QAEX$$QAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -373,6 +380,7 @@ EXPORTS
??BCord@absl@@QBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
??BStatusBuilder@absl@@QGBE?AVStatus@1@XZ
??Bint128@absl@@QBENXZ
+ ??EChunkIterator@Cord@absl@@QAEAAV012@XZ
??Eiterator@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@QAEAAV0123@XZ
??Gdetail@cctz@time_internal@absl@@YA?AV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@0123@V40123@_J@Z
??Kabsl@@YA?AVint128@0@V10@0@Z
@@ -392,7 +400,6 @@ EXPORTS
??R<lambda_2>@?0???$emplace_back@PBVCommandLineFlag@absl@@@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCommandLineFlag@absl@@$$QAPBV45@@Z@QBE?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$$QAU4567@@Z@QBE?A?<auto>@@XZ
??R<lambda_2>@?0???$emplace_back@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@?$vector@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@$$QAV423@@Z@QBE?A?<auto>@@XZ
- ??R?$ConvertToContainer@V?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@__Cr@std@@ABV123@@Z
??R?$ConvertToContainer@V?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@$0A@@?$Splitter@VByChar@absl@@UAllowEmpty@2@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@strings_internal@absl@@QBE?AV?$vector@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$allocator@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@ABV123@@Z
??RByCivilTime@Transition@cctz@time_internal@absl@@QBE_NABU1234@0@Z
??RDynValueDeleter@flags_internal@absl@@QBEXPAX@Z
@@ -559,6 +566,7 @@ EXPORTS
?ConvertFloatImpl@str_format_internal@absl@@YA_NMABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NNABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
?ConvertFloatImpl@str_format_internal@absl@@YA_NOABVFormatConversionSpecImpl@12@PAVFormatSinkImpl@12@@Z
+ ?ConvertOne@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NABUUnboundConversion@34@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Copy@container_internal@absl@@YAXAAVCommonFields@12@ABUPolicyFunctions@12@ABV312@V?$FunctionRef@$$A6AXPAXPBX@Z@2@@Z
?CopyCordToSpan@absl@@YAIABVCord@1@V?$Span@D@1@@Z
?CopyCordToString@absl@@YAXABVCord@1@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
@@ -574,7 +582,6 @@ EXPORTS
?CurrentThreadIdentityIfPresent@base_internal@absl@@YAPAUThreadIdentity@12@XZ
?CurrentValue@FlagImpl@flags_internal@absl@@EBE?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?DataGuard@FlagImpl@flags_internal@absl@@ABEAAVMutex@3@XZ
- ?DeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAXIPAW4ctrl_t@12@II_NI@Z1@Z
?DecodeFrom@ProtoField@log_internal@absl@@QAE_NPAV?$Span@$$CBD@3@@Z
?DecodeRustPunycode@debugging_internal@absl@@YAPADUDecodeRustPunycodeOptions@12@@Z
?DecodeWaitCycles@SpinLock@base_internal@absl@@KA_JI@Z
@@ -598,8 +605,6 @@ EXPORTS
?DestroyContents@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@AAEXXZ
?DestroyCordSlow@Cord@absl@@AAEXXZ
?DestroySlots@container_internal@absl@@YAXAAVCommonFields@12@IP6AXPAX1@Z@Z
- ?DestructNonSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
- ?DestructSoo@container_internal@absl@@YAXAAVCommonFields@12@IIP6AXPAX1@ZP6AX1IPAW4ctrl_t@12@II_NI@Z1@Z
?DiagnosticsGetDeleteQueue@CordzHandle@cord_internal@absl@@SA?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsGetSafeToInspectDeletedHandles@CordzHandle@cord_internal@absl@@QAE?AV?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@XZ
?DiagnosticsHandleIsSafeToInspect@CordzHandle@cord_internal@absl@@QBE_NPBV123@@Z
@@ -793,7 +798,7 @@ EXPORTS
?GetFlagsHelpMatchSubstr@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@XZ
?GetFlagsHelpMode@flags_internal@absl@@YA?AW4HelpMode@12@XZ
?GetFlatAux@Cord@absl@@CA_NPAUCordRep@cord_internal@2@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ?GetGrowthLeftTotalSlow@GrowthInfoAccessor@container_internal@absl@@QBEII@Z
+ ?GetGrowthLeftTotalSlow@CommonFields@container_internal@absl@@QBEII@Z
?GetHashtablezMaxSamples@container_internal@absl@@YAIXZ
?GetHashtablezSampleParameter@container_internal@absl@@YAHXZ
?GetId@GraphCycles@synchronization_internal@absl@@QAE?AUGraphId@23@PAX@Z
@@ -850,11 +855,10 @@ EXPORTS
?InNanosecondsFromNow@KernelTimeout@synchronization_internal@absl@@ABE_JXZ
?IncrementOverflow@RefcountAndFlags@cord_internal@absl@@SAXXZ
?IncrementSynchSem@Mutex@absl@@CAXPAV12@PAUPerThreadSynch@base_internal@2@@Z
- ?Init@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCordRepBtree@23@@Z
?Init@FlagImpl@flags_internal@absl@@AAEXXZ
?InitDiscreteDistribution@random_internal@absl@@YA?AV?$vector@U?$pair@NI@__Cr@std@@V?$allocator@U?$pair@NI@__Cr@std@@@23@@__Cr@std@@PAV?$vector@NV?$allocator@N@__Cr@std@@@45@@Z
?InitFrom@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXABV123@@Z
- ?InitGrowthLeftNoDeleted@GrowthInfoAccessor@container_internal@absl@@QAEXII@Z
+ ?InitGrowthLeftNoDeleted@CommonFields@container_internal@absl@@QAEXII@Z
?InitRepImpl@StatusBuilder@absl@@CAPAURep@12@VStatus@2@@Z
?InitSigSafeArena@base_internal@absl@@YAXXZ
?InitStream@Rep@StatusBuilder@absl@@QAEXXZ
@@ -972,7 +976,6 @@ EXPORTS
?NewArena@LowLevelAlloc@base_internal@absl@@SAPAUArena@123@I@Z
?NewInternal@CRCImpl@crc_internal@absl@@SAPAV123@XZ
?NewString@CheckOpMessageBuilder@log_internal@absl@@QAEPBDXZ
- ?Next@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?Next@CordzInfo@cord_internal@absl@@QBEPAV123@ABVCordzSnapshot@23@@Z
?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
@@ -993,7 +996,7 @@ EXPORTS
?OnVLogVerbosityUpdate@log_internal@absl@@YAXV?$function@$$A6AXXZ@__Cr@std@@@Z
?OneTimeInitThreadIdentity@synchronization_internal@absl@@YAXPAUThreadIdentity@base_internal@2@@Z
?OneWordValue@FlagImpl@flags_internal@absl@@ABEAAU?$atomic@_J@__Cr@std@@XZ
- ?OverwriteFullAsEmpty@GrowthInfoAccessor@container_internal@absl@@QAEXXZ
+ ?OverwriteFullAsEmpty@CommonFields@container_internal@absl@@QAEXXZ
?ParseAbseilFlagsOnly@absl@@YAXHQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@34@@Z
?ParseAbseilFlagsOnlyImpl@flags_internal@absl@@YA?AW4HelpMode@12@HQAPADAAV?$vector@PADV?$allocator@PAD@__Cr@std@@@__Cr@std@@AAV?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@56@W4UsageFlagsAction@12@@Z
?ParseCivilTime@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$civil_time@Uday_tag@time_internal@absl@@@detail@cctz@time_internal@1@@Z
@@ -1067,8 +1070,8 @@ EXPORTS
?ReadSeedMaterialFromOSEntropy@random_internal@absl@@YA_NV?$Span@I@2@@Z
?ReadSequenceLockedData@FlagImpl@flags_internal@absl@@ABEXPAX@Z
?ReaderTryLockSlow@Mutex@absl@@AAE_NXZ
- ?RebalanceGrowthLeftLowerBound@GrowthInfoAccessor@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
- ?RebalanceGrowthLeftLowerBoundLargeCapacity@GrowthInfoAccessor@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
+ ?RebalanceGrowthLeftLowerBound@CommonFields@container_internal@absl@@QAE?AVGrowthInfoLowerBound@23@I@Z
+ ?RebalanceGrowthLeftLowerBoundLargeCapacity@CommonFields@container_internal@absl@@AAE?AVGrowthInfoLowerBound@23@XZ
?Rebuild@CordRepBtree@cord_internal@absl@@CAXPAPAV123@PAV123@_N@Z
?Rebuild@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@@Z
?RecordClearedReservationSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
@@ -1333,6 +1336,7 @@ EXPORTS
?UnparseFlag@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VDuration@1@@Z
?Unref@StatusRep@status_internal@absl@@QBEXXZ
?UnrefTree@InlineRep@Cord@absl@@AAEXXZ
+ ?UnregisterAndDeallocBackingArray@container_internal@absl@@YAXAAVCommonFields@12@ABUDtorPolicy@12@P6AXPAX2I@Z2@Z
?UnsampleSlow@container_internal@absl@@YAXPAUHashtablezInfo@12@@Z
?Unscramble@CRC32@crc_internal@absl@@UBEXPAI@Z
?Untrack@CordzInfo@cord_internal@absl@@QAEXXZ
diff --git a/deps/v8/third_party/dragonbox/README.v8 b/deps/v8/third_party/dragonbox/README.v8
index 75660d64759..03d88e11840 100644
--- a/deps/v8/third_party/dragonbox/README.v8
+++ b/deps/v8/third_party/dragonbox/README.v8
@@ -4,7 +4,7 @@ Version: 1.1.3
Revision: 6c7c925b571d54486b9ffae8d9d18a822801cbda
Update Mechanism: Autoroll
License: Apache-with-LLVM-Exception, BSL-1.0
-License File: src/LICENSE-Apache2-LLVM, src/LICENSE-Boost
+License File: //third_party/dragonbox/src/LICENSE-Apache2-LLVM, //third_party/dragonbox/src/LICENSE-Boost
Shipped: yes
Security Critical: yes
CPEPrefix: unknown
diff --git a/deps/v8/third_party/fast_float/README.v8 b/deps/v8/third_party/fast_float/README.v8
index f43ffb4c093..9f74c1ce795 100644
--- a/deps/v8/third_party/fast_float/README.v8
+++ b/deps/v8/third_party/fast_float/README.v8
@@ -4,7 +4,7 @@ Version: 7.0.0
Revision: cb1d42aaa1e14b09e1452cfdef373d051b8c02a4
Update Mechanism: Autoroll
License: MIT
-License File: src/LICENSE-MIT
+License File: //third_party/fast_float/src/LICENSE-MIT
Shipped: yes
Security Critical: yes
CPEPrefix: unknown
diff --git a/deps/v8/third_party/fast_float/src/include/fast_float/ascii_number.h b/deps/v8/third_party/fast_float/src/include/fast_float/ascii_number.h
index e6ead45bb80..52f1e8425f7 100644
--- a/deps/v8/third_party/fast_float/src/include/fast_float/ascii_number.h
+++ b/deps/v8/third_party/fast_float/src/include/fast_float/ascii_number.h
@@ -32,7 +32,7 @@ template <typename UC> fastfloat_really_inline constexpr bool has_simd_opt() {
// able to optimize it well.
template <typename UC>
fastfloat_really_inline constexpr bool is_integer(UC c) noexcept {
- return (unsigned)(c - UC('0')) <= 9u;
+ return static_cast<unsigned>(c - UC('0')) <= 9u;
}
fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
@@ -223,8 +223,8 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars,
return false;
FASTFLOAT_SIMD_RESTORE_WARNINGS
#else
- (void)chars;
- (void)i;
+ static_cast<void>(chars);
+ static_cast<void>(i);
return false;
#endif // FASTFLOAT_SSE2
}
@@ -268,10 +268,9 @@ loop_parse_if_eight_digits(char const *&p, char const *const pend,
}
// Consume a remaining 4-7 digit run in a single SWAR step instead of
// byte-by-byte (reuses the existing 4-digit helpers). The parsed result is
- // identical either way. Gated to clang: on gcc the extra 4-digit check
- // regresses inputs whose remainder is shorter than 4 digits (it becomes pure
- // overhead there); clang does not show that.
-#if defined(__clang__)
+ // identical either way. Historically gated to clang because gcc regressed on
+ // short remainders, but that verdict predates the span-elision restructure;
+ // with the leaner hot path the 4-digit step now wins on gcc as well.
if ((pend - p) >= 4) {
uint32_t const val4 = read4_to_u32(p);
if (is_made_of_four_digits_fast(val4)) {
@@ -280,7 +279,6 @@ loop_parse_if_eight_digits(char const *&p, char const *const pend,
p += 4;
}
}
-#endif
}
enum class parse_error {
@@ -289,7 +287,7 @@ enum class parse_error {
missing_integer_after_sign,
// A sign must be followed by an integer or dot.
missing_integer_or_dot_after_sign,
- // [JSON-only] The integer part must not have leading zeros.
+ // [JSON/JavaScript-only] The integer part must not have leading zeros.
leading_zeros_in_integer_part,
// [JSON-only] The integer part must have at least one digit.
no_digits_in_integer_part,
@@ -300,6 +298,10 @@ enum class parse_error {
no_digits_in_mantissa,
// Scientific notation requires an exponential part.
missing_exponential_part,
+ // [JavaScript-only, sloppy mode] The integer part is a legacy octal literal
+ // (a leading zero followed by octal digits only), which is not a decimal
+ // number. Parse it in base 8 instead.
+ legacy_octal_integer_part,
};
template <typename UC> struct parsed_number_string_t {
@@ -422,6 +424,30 @@ parse_number_string(UC const *p, UC const *pend, parse_options_t<UC> options,
parse_error::leading_zeros_in_integer_part);
}
}
+ else if (uint64_t(fmt & detail::basic_javascript_fmt)) {
+ // ECMAScript DecimalIntegerLiteral is "0" or a non-zero digit followed by
+ // digits: no leading zeros. Unlike JSON, the integer part may be empty
+ // (".5"); the no_digits_in_mantissa check below still rejects ".".
+ if ((digit_count > 1) && (start_digits[0] == UC('0'))) {
+ if (!uint64_t(fmt & detail::basic_javascript_sloppy_fmt)) {
+ return report_parse_error<UC>(
+ start_digits, parse_error::leading_zeros_in_integer_part);
+ }
+ // Sloppy mode (Annex B): a NonOctalDecimalIntegerLiteral has a leading
+ // zero and at least one digit that is 8 or 9 ("08.5" is 8.5). With
+ // octal digits only, it is a LegacyOctalIntegerLiteral ("0775"), which
+ // is not a decimal number: report it so the caller can parse it in
+ // base 8.
+ bool has_non_octal_digit = false;
+ for (UC const *q = start_digits; q != end_of_integer_part; ++q) {
+ has_non_octal_digit |= (*q >= UC('8'));
+ }
+ if (!has_non_octal_digit) {
+ return report_parse_error<UC>(start_digits,
+ parse_error::legacy_octal_integer_part);
+ }
+ }
+ }
int64_t exponent = 0;
bool const has_decimal_point = (p != pend) && (*p == decimal_point);
@@ -603,7 +629,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
FASTFLOAT_IF_CONSTEXPR17(
(std::is_same<T, std::uint8_t>::value && sizeof(UC) == 1)) {
if (base == 10) {
- const size_t len = (size_t)(pend - p);
+ const size_t len = static_cast<size_t>(pend - p);
if (len == 0) {
if (has_leading_zeros) {
value = 0;
@@ -648,9 +674,10 @@ parse_int_string(UC const *p, UC const *pend, T &value,
uint32_t magic =
((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
- uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32
+ uint32_t tz =
+ static_cast<uint32_t>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
- nd = (uint32_t)(nd < len ? nd : len);
+ nd = static_cast<uint32_t>(nd < len ? nd : len);
if (nd == 0) {
if (has_leading_zeros) {
value = 0;
@@ -686,7 +713,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
answer.ptr = p + nd;
return answer;
}
- value = (uint8_t)((0x640a01 * digits) >> 24);
+ value = static_cast<uint8_t>((0x640a01 * digits) >> 24);
answer.ec = std::errc();
answer.ptr = p + nd;
return answer;
@@ -806,7 +833,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
// check other types overflow
if (!std::is_same<T, uint64_t>::value) {
- if (i > uint64_t(std::numeric_limits<T>::max()) + uint64_t(negative)) {
+ if (i > uint64_t((std::numeric_limits<T>::max)()) + uint64_t(negative)) {
answer.ec = std::errc::result_out_of_range;
return answer;
}
@@ -823,8 +850,8 @@ parse_int_string(UC const *p, UC const *pend, T &value,
// - reinterpret_casting (~i + 1) would work, but it is not constexpr
// this is always optimized into a neg instruction (note: T is an integer
// type)
- value = T(-std::numeric_limits<T>::max() -
- T(i - uint64_t(std::numeric_limits<T>::max())));
+ value = T(-(std::numeric_limits<T>::max)() -
+ T(i - uint64_t((std::numeric_limits<T>::max)())));
#ifdef FASTFLOAT_VISUAL_STUDIO
#pragma warning(pop)
#endif
diff --git a/deps/v8/third_party/fast_float/src/include/fast_float/bigint.h b/deps/v8/third_party/fast_float/src/include/fast_float/bigint.h
index 74901e3956f..665debb7213 100644
--- a/deps/v8/third_party/fast_float/src/include/fast_float/bigint.h
+++ b/deps/v8/third_party/fast_float/src/include/fast_float/bigint.h
@@ -619,8 +619,8 @@ struct bigint : pow5_tables<> {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
// This is similar to https://github.com/llvm/llvm-project/issues/47746,
// except the workaround described there don't work here
- FASTFLOAT_TRY(small_mul(
- vec, limb(((void)small_power_of_5[0], small_power_of_5[exp]))));
+ FASTFLOAT_TRY(small_mul(vec, limb((static_cast<void>(small_power_of_5[0]),
+ small_power_of_5[exp]))));
}
return true;
diff --git a/deps/v8/third_party/fast_float/src/include/fast_float/digit_comparison.h b/deps/v8/third_party/fast_float/src/include/fast_float/digit_comparison.h
index c2c83b0cf5f..70085bed22b 100644
--- a/deps/v8/third_party/fast_float/src/include/fast_float/digit_comparison.h
+++ b/deps/v8/third_party/fast_float/src/include/fast_float/digit_comparison.h
@@ -400,8 +400,8 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
round<T>(answer, [ord](adjusted_mantissa &a, int32_t shift) {
round_nearest_tie_even(
a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
- (void)_; // not needed, since we've done our comparison
- (void)__; // not needed, since we've done our comparison
+ static_cast<void>(_); // not needed, since we've done our comparison
+ static_cast<void>(__); // not needed, since we've done our comparison
if (ord > 0) {
return true;
} else if (ord < 0) {
diff --git a/deps/v8/third_party/fast_float/src/include/fast_float/float_common.h b/deps/v8/third_party/fast_float/src/include/fast_float/float_common.h
index 405513768e0..87c72b0ebda 100644
--- a/deps/v8/third_party/fast_float/src/include/fast_float/float_common.h
+++ b/deps/v8/third_party/fast_float/src/include/fast_float/float_common.h
@@ -17,8 +17,8 @@
#include "constexpr_feature_detect.h"
#define FASTFLOAT_VERSION_MAJOR 8
-#define FASTFLOAT_VERSION_MINOR 2
-#define FASTFLOAT_VERSION_PATCH 10
+#define FASTFLOAT_VERSION_MINOR 3
+#define FASTFLOAT_VERSION_PATCH 0
#define FASTFLOAT_STRINGIZE_IMPL(x) #x
#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
@@ -39,6 +39,8 @@ enum class chars_format : uint64_t;
namespace detail {
constexpr chars_format basic_json_fmt = chars_format(1 << 5);
constexpr chars_format basic_fortran_fmt = chars_format(1 << 6);
+constexpr chars_format basic_javascript_fmt = chars_format(1 << 9);
+constexpr chars_format basic_javascript_sloppy_fmt = chars_format(1 << 10);
} // namespace detail
enum class chars_format : uint64_t {
@@ -54,6 +56,24 @@ enum class chars_format : uint64_t {
general = fixed | scientific,
allow_leading_plus = 1 << 7,
skip_white_space = 1 << 8,
+ // ECMAScript DecimalLiteral (strict mode):
+ // https://tc39.es/ecma262/#prod-DecimalLiteral
+ // Like JSON, the integer part must not have leading zeros ("01" is
+ // rejected), but unlike JSON the integer part may be empty (".5") and the
+ // fractional part may be empty ("5.", "5.e3"). A leading minus sign is
+ // accepted, and a leading plus sign with allow_leading_plus.
+ javascript =
+ uint64_t(detail::basic_javascript_fmt) | fixed | scientific | no_infnan,
+ // ECMAScript DecimalLiteral in sloppy mode, which adds Annex B's
+ // NonOctalDecimalIntegerLiteral: a leading zero is accepted when one of
+ // the digits is 8 or 9 ("08.5" is 8.5). A leading zero followed only by
+ // octal digits is a LegacyOctalIntegerLiteral ("0775"): it is not a
+ // decimal number, so it is rejected with legacy_octal_integer_part and the
+ // caller may parse it in base 8.
+ // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
+ javascript_sloppy = uint64_t(detail::basic_javascript_fmt) |
+ uint64_t(detail::basic_javascript_sloppy_fmt) | fixed |
+ scientific | no_infnan,
};
template <typename UC> struct from_chars_result_t {
@@ -225,12 +245,12 @@ using parse_options = parse_options_t<char>;
#ifndef FASTFLOAT_ASSERT
#define FASTFLOAT_ASSERT(x) \
- { ((void)(x)); }
+ { static_cast<void>(x); }
#endif
#ifndef FASTFLOAT_DEBUG_ASSERT
#define FASTFLOAT_DEBUG_ASSERT(x) \
- { ((void)(x)); }
+ { static_cast<void>(x); }
#endif
// rust style `try!()` macro, or `?` operator
@@ -509,7 +529,7 @@ leading_zeroes(uint64_t input_num) {
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
_BitScanReverse64(&leading_zero, input_num);
- return (int)(63 - leading_zero);
+ return static_cast<int>(63 - leading_zero);
#else
return leading_zeroes_generic(input_num);
#endif
@@ -556,7 +576,7 @@ countr_zero_32(uint32_t input_num) {
#ifdef FASTFLOAT_VISUAL_STUDIO
unsigned long trailing_zero = 0;
if (_BitScanForward(&trailing_zero, input_num)) {
- return (int)trailing_zero;
+ return static_cast<int>(trailing_zero);
}
return 32;
#else
@@ -566,18 +586,21 @@ countr_zero_32(uint32_t input_num) {
// slow emulation routine for 32-bit
fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) {
- return x * (uint64_t)y;
+ return x * static_cast<uint64_t>(y);
}
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t
umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
- uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd);
- uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd);
- uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32));
- uint64_t adbc_carry = (uint64_t)(adbc < ad);
+ uint64_t ad =
+ emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd));
+ uint64_t bd = emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd));
+ uint64_t adbc =
+ ad + emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd >> 32));
+ uint64_t adbc_carry = static_cast<uint64_t>(adbc < ad);
uint64_t lo = bd + (adbc << 32);
- *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) +
- (adbc_carry << 32) + (uint64_t)(lo < bd);
+ *hi =
+ emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd >> 32)) +
+ (adbc >> 32) + (adbc_carry << 32) + static_cast<uint64_t>(lo < bd);
return lo;
}
@@ -612,7 +635,7 @@ full_multiplication(uint64_t a, uint64_t b) {
!defined(_M_ARM64) && !defined(__GNUC__))
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
#elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__)
- __uint128_t r = ((__uint128_t)a) * b;
+ __uint128_t r = static_cast<__uint128_t>(a) * b;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
#else
@@ -874,7 +897,7 @@ template <>
inline constexpr std::float16_t
binary_format<std::float16_t>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)powers_of_ten[0], powers_of_ten[power];
+ return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
}
template <>
@@ -918,7 +941,7 @@ binary_format<std::float16_t>::max_mantissa_fast_path(int64_t power) {
// power >= 0 && power <= 4
//
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)max_mantissa[0], max_mantissa[power];
+ return static_cast<void>(max_mantissa[0]), max_mantissa[power];
}
template <>
@@ -997,7 +1020,7 @@ template <>
inline constexpr std::bfloat16_t
binary_format<std::bfloat16_t>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)powers_of_ten[0], powers_of_ten[power];
+ return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
}
template <>
@@ -1041,7 +1064,7 @@ binary_format<std::bfloat16_t>::max_mantissa_fast_path(int64_t power) {
// power >= 0 && power <= 3
//
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)max_mantissa[0], max_mantissa[power];
+ return static_cast<void>(max_mantissa[0]), max_mantissa[power];
}
template <>
@@ -1098,7 +1121,7 @@ binary_format<double>::max_mantissa_fast_path(int64_t power) {
// power >= 0 && power <= 22
//
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)max_mantissa[0], max_mantissa[power];
+ return static_cast<void>(max_mantissa[0]), max_mantissa[power];
}
template <>
@@ -1108,20 +1131,20 @@ binary_format<float>::max_mantissa_fast_path(int64_t power) {
// power >= 0 && power <= 10
//
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)max_mantissa[0], max_mantissa[power];
+ return static_cast<void>(max_mantissa[0]), max_mantissa[power];
}
template <>
inline constexpr double
binary_format<double>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)powers_of_ten[0], powers_of_ten[power];
+ return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
}
template <>
inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
- return (void)powers_of_ten[0], powers_of_ten[power];
+ return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
}
template <> inline constexpr int binary_format<double>::largest_power_of_ten() {
@@ -1223,7 +1246,11 @@ template <typename T> constexpr bool space_lut<T>::value[];
#endif
template <typename UC> constexpr bool is_space(UC c) {
- return c < 256 && space_lut<>::value[uint8_t(c)];
+ // wchar_t and char can be signed, so a negative code unit slips past a plain
+ // `c < 256` and then indexes the table by its truncated low byte. Compare as
+ // unsigned, matching the care taken in ch_to_digit.
+ using UnsignedUC = typename std::make_unsigned<UC>::type;
+ return static_cast<UnsignedUC>(c) < 256 && space_lut<>::value[uint8_t(c)];
}
template <typename UC> static constexpr uint64_t int_cmp_zeros() {
diff --git a/deps/v8/third_party/fast_float/src/include/fast_float/parse_number.h b/deps/v8/third_party/fast_float/src/include/fast_float/parse_number.h
index 5d11dfad5ed..58cdafd51c5 100644
--- a/deps/v8/third_party/fast_float/src/include/fast_float/parse_number.h
+++ b/deps/v8/third_party/fast_float/src/include/fast_float/parse_number.h
@@ -96,7 +96,7 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
// asm). The value does not need to be std::numeric_limits<float>::min(), any
// small value so that 1 + x should round to 1 would do (after accounting for
// excess precision, as in 387 instructions).
- static float volatile fmin = std::numeric_limits<float>::min();
+ static float volatile fmin = (std::numeric_limits<float>::min)();
float fmini = fmin; // we copy it so that it gets loaded at most once.
//
// Explanation:
@@ -198,7 +198,14 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
// We proceed optimistically, assuming that detail::rounds_to_nearest()
// returns true.
if (binary_format<T>::min_exponent_fast_path() <= exponent &&
- exponent <= binary_format<T>::max_exponent_fast_path()) {
+ exponent <= binary_format<T>::max_exponent_fast_path() &&
+ mantissa <= binary_format<T>::max_mantissa_fast_path()) {
+ // The mantissa bound above is a necessary condition for BOTH branches
+ // below: the rounding-mode-dependent branch checks the tighter
+ // max_mantissa_fast_path(exponent) <= max_mantissa_fast_path(). Testing
+ // it before detail::rounds_to_nearest() spares long-mantissa inputs
+ // (which can never take the fast path) the volatile-float probe.
+ //
// Unfortunately, the conventional Clinger's fast path is only possible
// when the system rounds to the nearest float.
//
@@ -209,18 +216,16 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
// We have that fegetround() == FE_TONEAREST.
// Next is Clinger's fast path.
- if (mantissa <= binary_format<T>::max_mantissa_fast_path()) {
- value = T(mantissa);
- if (exponent < 0) {
- value = value / binary_format<T>::exact_power_of_ten(-exponent);
- } else {
- value = value * binary_format<T>::exact_power_of_ten(exponent);
- }
- if (is_negative) {
- value = -value;
- }
- return true;
+ value = T(mantissa);
+ if (exponent < 0) {
+ value = value / binary_format<T>::exact_power_of_ten(-exponent);
+ } else {
+ value = value * binary_format<T>::exact_power_of_ten(exponent);
+ }
+ if (is_negative) {
+ value = -value;
}
+ return true;
} else {
// We do not have that fegetround() == FE_TONEAREST.
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's
diff --git a/deps/v8/third_party/googletest/README.chromium b/deps/v8/third_party/googletest/README.chromium
index 0f1f3e3b96e..73f77e45d96 100644
--- a/deps/v8/third_party/googletest/README.chromium
+++ b/deps/v8/third_party/googletest/README.chromium
@@ -4,7 +4,7 @@ URL: https://github.com/google/googletest.git
Version: 1.8.0.git-9518a57428ae0a7ed450c1361768e84a2a38af5a
Update Mechanism: Autoroll
License: BSD-3-Clause
-License File: src/LICENSE
+License File: //third_party/googletest/src/LICENSE
Shipped: no
Security critical: no
diff --git a/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD b/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD
deleted file mode 100644
index a146efbe3a2..00000000000
--- a/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD
+++ /dev/null
@@ -1,310 +0,0 @@
-load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
-load("@rules_cc//cc:cc_library.bzl", "cc_library")
-load("@rules_cc//cc:cc_test.bzl", "cc_test")
-
-package(
- default_applicable_licenses = ["//:license"],
- default_visibility = ["//visibility:public"],
-)
-
-licenses(["notice"])
-
-# Unused on Bazel builds, where this is not defined/known; Copybara replaces
-# usages with an empty list.
-COMPAT = [
- "//buildenv/target:non_prod", # includes mobile/vendor.
-]
-
-cc_library(
- name = "intel",
- # hdrs = select({
- # "//third_party/bazel_platforms/cpu:x86_64": [
- # "avx512-16bit-common.h",
- # "avx512-16bit-qsort.hpp",
- # "avx512-32bit-qsort.hpp",
- # "avx512-64bit-common.h",
- # "avx512-64bit-qsort.hpp",
- # "avx512-common-qsort.h",
- # ],
- # "//conditions:default": [],
- # }),
- compatible_with = [],
-)
-
-cc_library(
- name = "vxsort",
- srcs = [
- # "vxsort/isa_detection.cpp",
- # "vxsort/isa_detection_msvc.cpp",
- # "vxsort/isa_detection_sane.cpp",
- # "vxsort/machine_traits.avx2.cpp",
- # "vxsort/smallsort/avx2_load_mask_tables.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.double.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.float.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.uint32_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX2.uint64_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.double.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.float.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.uint32_t.generated.cpp",
- # "vxsort/smallsort/bitonic_sort.AVX512.uint64_t.generated.cpp",
- # "vxsort/vxsort_stats.cpp",
- ],
- hdrs = [
- # "vxsort/alignment.h",
- # "vxsort/defs.h",
- # "vxsort/isa_detection.h",
- # "vxsort/machine_traits.avx2.h",
- # "vxsort/machine_traits.avx512.h",
- # "vxsort/machine_traits.h",
- # "vxsort/packer.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.double.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.float.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.int32_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.int64_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.uint32_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX2.uint64_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.double.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.float.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.int32_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.int64_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.uint32_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.AVX512.uint64_t.generated.h",
- # "vxsort/smallsort/bitonic_sort.h",
- # "vxsort/vxsort.h",
- # "vxsort/vxsort_stats.h",
- ],
- compatible_with = [],
- textual_hdrs = [
- # "vxsort/vxsort_targets_disable.h",
- # "vxsort/vxsort_targets_enable_avx2.h",
- # "vxsort/vxsort_targets_enable_avx512.h",
- ],
-)
-
-VQSORT_SRCS = [
- # Split into separate files to reduce MSVC build time.
- "vqsort_128a.cc",
- "vqsort_128d.cc",
- "vqsort_f16a.cc",
- "vqsort_f16d.cc",
- "vqsort_f32a.cc",
- "vqsort_f32d.cc",
- "vqsort_f64a.cc",
- "vqsort_f64d.cc",
- "vqsort_i16a.cc",
- "vqsort_i16d.cc",
- "vqsort_i32a.cc",
- "vqsort_i32d.cc",
- "vqsort_i64a.cc",
- "vqsort_i64d.cc",
- # vqsort_kv64a.cc is in :vqsort_k32v32 and vqsort.cc is in :vqsort_shared.
- "vqsort_kv128a.cc",
- "vqsort_kv128d.cc",
- "vqsort_u16a.cc",
- "vqsort_u16d.cc",
- "vqsort_u32a.cc",
- "vqsort_u32d.cc",
- "vqsort_u64a.cc",
- "vqsort_u64d.cc",
-]
-
-VQSORT_TEXTUAL_HDRS = [
- "shared-inl.h",
- "sorting_networks-inl.h",
- "traits-inl.h",
- "traits128-inl.h",
- "vqsort-inl.h",
- # Placeholder for internal instrumentation. Do not remove.
-]
-
-# both :vqsort_k32v32 and :vqsort depend on this.
-cc_library(
- name = "vqsort_shared",
- srcs = [
- "vqsort.cc",
- ],
- hdrs = [
- "order.h", # part of public interface, included by vqsort.h
- "vqsort.h", # public interface
- ],
- compatible_with = [],
- local_defines = ["hwy_contrib_EXPORTS"],
- textual_hdrs = VQSORT_TEXTUAL_HDRS,
- deps = [
- "//:algo",
- "//:hwy",
- ],
-)
-
-cc_library(
- name = "vqsort_k32v32",
- srcs = [
- "vqsort_kv64a.cc",
- "vqsort_kv64d.cc",
- ],
- hdrs = [
- "order.h", # part of public interface, included by vqsort.h
- "vqsort.h", # public interface
- ],
- compatible_with = [],
- local_defines = ["hwy_contrib_EXPORTS"],
- textual_hdrs = VQSORT_TEXTUAL_HDRS,
- deps = [
- ":vqsort_shared",
- "//:algo",
- "//:hwy",
- ],
-)
-
-cc_library(
- name = "vqsort",
- srcs = VQSORT_SRCS,
- hdrs = [
- "order.h", # part of public interface, included by vqsort.h
- "vqsort.h", # public interface
- ],
- compatible_with = [],
- local_defines = ["hwy_contrib_EXPORTS"],
- textual_hdrs = VQSORT_TEXTUAL_HDRS,
- deps = [
- ":intel", # required if HAVE_INTEL
- ":vqsort_k32v32",
- ":vqsort_shared",
- ":vxsort", # required if HAVE_VXSORT
- "//:algo",
- "//:hwy",
- "//:nanobenchmark",
- ],
-)
-
-# -----------------------------------------------------------------------------
-# Internal-only targets
-
-# Same as vqsort, but add HWY_COMPILE_ALL_ATTAINABLE to ensure we cover all
-# targets. Do not enable this in the main vqsort because it increases
-# compile times.
-cc_library(
- name = "vqsort_for_test",
- srcs = VQSORT_SRCS,
- hdrs = [
- "order.h", # part of public interface, included by vqsort.h
- "vqsort.h", # public interface
- ],
- compatible_with = [],
- local_defines = [
- "hwy_contrib_EXPORTS",
- # Build for all targets because sort_test will dynamic-dispatch to all.
- "HWY_COMPILE_ALL_ATTAINABLE",
- ],
- textual_hdrs = VQSORT_TEXTUAL_HDRS,
- deps = [
- "//:algo",
- "//:hwy",
- "//:nanobenchmark",
- ],
-)
-
-cc_library(
- name = "helpers",
- testonly = 1,
- textual_hdrs = [
- "algo-inl.h",
- "result-inl.h",
- ],
- deps = [
- ":vqsort",
- "//:nanobenchmark",
- # Required for HAVE_PDQSORT, but that is unused and this is
- # unavailable to Bazel builds, hence commented out.
- # "//third_party/boost/allowed",
- # Avoid ips4o and thus TBB to work around hwloc build failure.
- ],
-)
-
-cc_binary(
- name = "print_network",
- testonly = 1,
- srcs = ["print_network.cc"],
- deps = [
- ":helpers",
- ":vqsort",
- "//:hwy",
- ],
-)
-
-TEST_MAIN = select({
- "//:compiler_msvc": [],
- "//conditions:default": ["@com_google_googletest//:gtest_main"],
-})
-
-cc_test(
- name = "sort_unit_test",
- size = "small",
- srcs = ["sort_unit_test.cc"],
- # Do not enable fully_static_link (pthread crash on bazel)
- local_defines = ["HWY_IS_TEST"],
- # for test_suite.
- tags = ["hwy_ops_test"],
- deps = [
- ":helpers",
- ":vqsort_for_test",
- "//:hwy",
- "//:hwy_test_util",
- ] + TEST_MAIN,
-)
-
-cc_test(
- name = "sort_test",
- size = "medium",
- timeout = "long",
- srcs = ["sort_test.cc"],
- # Do not enable fully_static_link (pthread crash on bazel)
- local_defines = ["HWY_IS_TEST"],
- # for test_suite.
- tags = ["hwy_ops_test"],
- deps = [
- ":helpers",
- ":vqsort_for_test",
- "//:hwy",
- "//:hwy_test_util",
- "//:thread_pool",
- "//:topology",
- ] + TEST_MAIN,
-)
-
-cc_test(
- name = "bench_sort",
- size = "medium",
- srcs = ["bench_sort.cc"],
- # Do not enable fully_static_link (pthread crash on bazel)
- local_defines = ["HWY_IS_TEST"],
- # for test_suite.
- tags = ["hwy_ops_test"],
- deps = [
- ":helpers",
- ":vqsort",
- "//:hwy",
- "//:hwy_test_util",
- "//:nanobenchmark",
- "//:thread_pool",
- ] + TEST_MAIN,
-)
-
-cc_binary(
- name = "bench_parallel",
- testonly = 1,
- srcs = ["bench_parallel.cc"],
- # Do not enable fully_static_link (pthread crash on bazel)
- local_defines = ["HWY_IS_TEST"],
- deps = [
- ":helpers",
- ":vqsort",
- "//:hwy",
- "//:hwy_test_util",
- "//:nanobenchmark",
- ] + TEST_MAIN,
-)
diff --git a/deps/v8/third_party/llvm-libc/README.v8 b/deps/v8/third_party/llvm-libc/README.v8
index bfe3cad208d..e85ebc4afd6 100644
--- a/deps/v8/third_party/llvm-libc/README.v8
+++ b/deps/v8/third_party/llvm-libc/README.v8
@@ -4,7 +4,7 @@ Version: N/A
Revision: DEPS
Update Mechanism: Autoroll
License: MIT, University of Illinois/NCSA Open Source License
-License File: src/LICENSE.TXT
+License File: //third_party/llvm-libc/src/LICENSE.TXT
Security Critical: yes
Shipped: yes
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
index 4d63860906f..fa01bc55785 100644
--- a/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
@@ -80,6 +80,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.fnmatch_macros
)
+add_proxy_header_library(
+ glob_macros
+ HDRS
+ glob_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.glob_macros
+)
+
add_proxy_header_library(
inet_address_macros
HDRS
@@ -178,6 +186,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.sys_epoll_macros
)
+add_proxy_header_library(
+ sys_file_macros
+ HDRS
+ sys_file_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.sys_file_macros
+)
+
add_proxy_header_library(
sys_ioctl_macros
HDRS
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/glob_macros.h b/deps/v8/third_party/llvm-libc/src/hdr/glob_macros.h
new file mode 100644
index 00000000000..194d2ca6afd
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/glob_macros.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for glob macros.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_GLOB_MACROS_H
+#define LLVM_LIBC_HDR_GLOB_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/glob-macros.h"
+
+#else // Overlay mode
+
+#include <glob.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_GLOB_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/sys_file_macros.h b/deps/v8/third_party/llvm-libc/src/hdr/sys_file_macros.h
new file mode 100644
index 00000000000..aa51277afec
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/sys_file_macros.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for macro values defined in sys/file.h
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_SYS_FILE_MACROS_H
+#define LLVM_LIBC_HDR_SYS_FILE_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/sys-file-macros.h"
+
+#else // Overlay mode
+
+#include <sys/file.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_SYS_FILE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/hdr/types/CMakeLists.txt
index dc15960c7a7..6949e73a78d 100644
--- a/deps/v8/third_party/llvm-libc/src/hdr/types/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/CMakeLists.txt
@@ -185,6 +185,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_passwd
)
+add_proxy_header_library(
+ struct_group
+ HDRS
+ struct_group.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_group
+)
+
add_proxy_header_library(
rsize_t
HDRS
@@ -406,6 +414,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.pthread_barrierattr_t
)
+add_proxy_header_library(
+ pthread_attr_t
+ HDRS
+ pthread_attr_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.pthread_attr_t
+)
+
add_proxy_header_library(
pthread_t
HDRS
@@ -473,6 +489,16 @@ add_proxy_header_library(
libc.include.stdio
)
+add_proxy_header_library(
+ off64_t
+ HDRS
+ off64_t.h
+ DEPENDS
+ libc.hdr.fcntl_overlay
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.off64_t
+)
+
add_proxy_header_library(
cookie_io_functions_t
HDRS
@@ -1310,6 +1336,14 @@ add_proxy_header_library(
libc.include.search
)
+add_proxy_header_library(
+ glob_t
+ HDRS
+ glob_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.glob_t
+)
+
add_proxy_header_library(
regex_t
HDRS
@@ -1365,3 +1399,11 @@ add_proxy_header_library(
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.tcflag_t
)
+
+add_proxy_header_library(
+ id_t
+ HDRS
+ id_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.id_t
+)
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/char8_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/char8_t.h
index 4d71e3dd890..76334b338cf 100644
--- a/deps/v8/third_party/llvm-libc/src/hdr/types/char8_t.h
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/char8_t.h
@@ -9,6 +9,23 @@
#ifndef LLVM_LIBC_HDR_TYPES_CHAR8_T_H
#define LLVM_LIBC_HDR_TYPES_CHAR8_T_H
+#ifdef LIBC_FULL_BUILD
+
#include "include/llvm-libc-types/char8_t.h"
+#else // Overlay mode
+
+// MacOS doesn't provide uchar.h so we use the types provided by LLVM-libc.
+#ifndef __APPLE__
+#include "hdr/uchar_overlay.h"
+#endif // !__APPLE__
+
+// Define char8_t in C++ for internal usage if it is not provided by compiler
+// or system uchar.h header.
+#ifndef __cpp_char8_t
+using char8_t = unsigned char;
+#endif // !__cpp_char8_t
+
+#endif // LIBC_FULL_BUILD
+
#endif // LLVM_LIBC_HDR_TYPES_CHAR8_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/glob_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/glob_t.h
new file mode 100644
index 00000000000..22bf5c3f019
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/glob_t.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for glob_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_GLOB_T_H
+#define LLVM_LIBC_HDR_TYPES_GLOB_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/glob_t.h"
+
+#else
+
+#include <glob.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_GLOB_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/id_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/id_t.h
new file mode 100644
index 00000000000..b478af776b7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/id_t.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy for id_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_ID_T_H
+#define LLVM_LIBC_HDR_TYPES_ID_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/id_t.h"
+
+#else // Overlay mode
+
+#include <sys/types.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_ID_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/off64_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/off64_t.h
new file mode 100644
index 00000000000..bf9d13c891c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/off64_t.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy for off64_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_OFF64_T_H
+#define LLVM_LIBC_HDR_TYPES_OFF64_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/off64_t.h"
+
+#else // Overlay mode
+
+#include "hdr/fcntl_overlay.h"
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_OFF64_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/pthread_attr_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/pthread_attr_t.h
new file mode 100644
index 00000000000..314692da3ab
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/pthread_attr_t.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy for pthread_attr_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_PTHREAD_ATTR_T_H
+#define LLVM_LIBC_HDR_TYPES_PTHREAD_ATTR_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/pthread_attr_t.h"
+
+#else // Overlay mode
+
+#include <pthread.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_PTHREAD_ATTR_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_group.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_group.h
new file mode 100644
index 00000000000..ce4d382e8f1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_group.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy for struct group.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_GROUP_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_GROUP_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_group.h"
+
+#else
+
+#include <grp.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_GROUP_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt
index 80f6f0e34cc..a45026de31e 100644
--- a/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt
@@ -69,6 +69,7 @@ add_header_macro(
.llvm-libc-types.struct_flock64
.llvm-libc-types.pid_t
.llvm-libc-types.off_t
+ .llvm-libc-types.off64_t
.llvm_libc_common_h
)
@@ -163,6 +164,17 @@ add_header_macro(
.llvm-libc-macros.float_macros
)
+add_header_macro(
+ glob
+ ../libc/include/glob.yaml
+ glob.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.glob_macros
+ .llvm-libc-types.glob_t
+ .llvm-libc-types.size_t
+)
+
add_header_macro(
grp
../libc/include/grp.yaml
@@ -454,6 +466,7 @@ add_header_macro(
DEPENDS
.llvm-libc-macros.signal_macros
.llvm-libc-types.pid_t
+ .llvm-libc-types.pthread_t
.llvm-libc-types.sig_atomic_t
.llvm-libc-types.sig_t
.llvm-libc-types.sighandler_t
@@ -713,6 +726,15 @@ add_header_macro(
.llvm-libc-macros.sys_epoll_macros
)
+add_header_macro(
+ sys_file
+ ../libc/include/sys/file.yaml
+ sys/file.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.sys_file_macros
+)
+
add_header_macro(
sys_ioctl
../libc/include/sys/ioctl.yaml
@@ -1046,6 +1068,15 @@ add_header_macro(
.llvm-libc-types.struct_sockaddr_un
)
+add_header_macro(
+ sys_user
+ ../libc/include/sys/user.yaml
+ sys/user.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-types.struct_user_regs_struct
+)
+
add_header_macro(
sys_vfs
../libc/include/sys/vfs.yaml
@@ -1066,6 +1097,16 @@ add_header_macro(
.llvm-libc-types.siginfo_t
)
+add_header_macro(
+ sys_xattr
+ ../libc/include/sys/xattr.yaml
+ sys/xattr.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-types.size_t
+ .llvm-libc-types.ssize_t
+)
+
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/net)
add_header_macro(
diff --git a/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml b/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml
index 43226b45505..49aac448e70 100644
--- a/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml
@@ -10,9 +10,22 @@ macros:
macro_header: fcntl-macros.h
- macro_name: AT_EACCESS
macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_NORMAL
+ macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_RANDOM
+ macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_SEQUENTIAL
+ macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_WILLNEED
+ macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_DONTNEED
+ macro_header: fcntl-macros.h
+ - macro_name: POSIX_FADV_NOREUSE
+ macro_header: fcntl-macros.h
types:
- type_name: mode_t
- type_name: off_t
+ - type_name: off64_t
- type_name: pid_t
- type_name: struct_f_owner_ex
- type_name: struct_flock
@@ -27,6 +40,15 @@ functions:
arguments:
- type: const char *
- type: mode_t
+ - name: fallocate
+ standards:
+ - linux
+ return_type: int
+ arguments:
+ - type: int
+ - type: int
+ - type: off_t
+ - type: off_t
- name: fcntl
standards:
- posix
@@ -52,3 +74,21 @@ functions:
- type: const char *
- type: int
- type: '...'
+ - name: posix_fadvise
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
+ - type: off_t
+ - type: off_t
+ - type: int
+ - name: posix_fadvise64
+ standards:
+ - gnu
+ return_type: int
+ arguments:
+ - type: int
+ - type: off64_t
+ - type: off64_t
+ - type: int
diff --git a/deps/v8/third_party/llvm-libc/src/include/glob.yaml b/deps/v8/third_party/llvm-libc/src/include/glob.yaml
new file mode 100644
index 00000000000..edc32b70b3e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/glob.yaml
@@ -0,0 +1,45 @@
+header: glob.h
+standards:
+ - posix
+macros:
+ - macro_name: GLOB_APPEND
+ macro_header: glob-macros.h
+ - macro_name: GLOB_DOOFFS
+ macro_header: glob-macros.h
+ - macro_name: GLOB_ERR
+ macro_header: glob-macros.h
+ - macro_name: GLOB_MARK
+ macro_header: glob-macros.h
+ - macro_name: GLOB_NOCHECK
+ macro_header: glob-macros.h
+ - macro_name: GLOB_NOESCAPE
+ macro_header: glob-macros.h
+ - macro_name: GLOB_NOSORT
+ macro_header: glob-macros.h
+ - macro_name: GLOB_ABORTED
+ macro_header: glob-macros.h
+ - macro_name: GLOB_NOMATCH
+ macro_header: glob-macros.h
+ - macro_name: GLOB_NOSPACE
+ macro_header: glob-macros.h
+types:
+ - type_name: glob_t
+ - type_name: size_t
+enums: []
+objects: []
+functions:
+ - name: glob
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *__restrict
+ - type: int
+ - type: int (*)(const char *, int)
+ - type: glob_t *__restrict
+ - name: globfree
+ standards:
+ - posix
+ return_type: void
+ arguments:
+ - type: glob_t *
diff --git a/deps/v8/third_party/llvm-libc/src/include/grp.yaml b/deps/v8/third_party/llvm-libc/src/include/grp.yaml
index 015d9c46e19..e1ace37cb9b 100644
--- a/deps/v8/third_party/llvm-libc/src/include/grp.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/grp.yaml
@@ -7,4 +7,39 @@ types:
- type_name: size_t
enums: []
objects: []
-functions: []
+functions:
+ - name: endgrent
+ standards:
+ - posix
+ return_type: void
+ arguments: []
+ - name: getgrent
+ standards:
+ - posix
+ return_type: struct group *
+ arguments: []
+ - name: getgrgid_r
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: gid_t
+ - type: struct group *
+ - type: char *
+ - type: size_t
+ - type: struct group **
+ - name: getgrnam_r
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: struct group *
+ - type: char *
+ - type: size_t
+ - type: struct group **
+ - name: setgrent
+ standards:
+ - posix
+ return_type: void
+ arguments: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/limits.yaml b/deps/v8/third_party/llvm-libc/src/include/limits.yaml
index f14aa9abed9..1d619984ff5 100644
--- a/deps/v8/third_party/llvm-libc/src/include/limits.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/limits.yaml
@@ -90,6 +90,8 @@ macros:
macro_header: limits-macros.h
- macro_name: SSIZE_MAX
macro_header: limits-macros.h
+ - macro_name: NZERO
+ macro_header: limits-macros.h
types: []
enums: []
objects: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/CMakeLists.txt
index e7f7d476594..9e9559056da 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/CMakeLists.txt
@@ -123,6 +123,12 @@ add_macro_header(
fnmatch-macros.h
)
+add_macro_header(
+ glob_macros
+ HDR
+ glob-macros.h
+)
+
add_macro_header(
file_seek_macros
HDR
@@ -258,6 +264,12 @@ add_macro_header(
.fcntl_macros
)
+add_macro_header(
+ sys_file_macros
+ HDR
+ sys-file-macros.h
+)
+
add_macro_header(
sys_ioctl_macros
HDR
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/CMakeLists.txt
index ea08c63c003..f3ee6af21d2 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/CMakeLists.txt
@@ -3,3 +3,9 @@ add_header(
HDR
time-macros.h
)
+
+add_header(
+ signal_macros
+ HDR
+ signal-macros.h
+)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/signal-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/signal-macros.h
new file mode 100644
index 00000000000..88bfcc3db62
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/darwin/signal-macros.h
@@ -0,0 +1,60 @@
+//===-- Definition of Darwin signal number macros -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
+#define LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
+
+#include "__llvm-libc-common.h"
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGINFO 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#define NSIG 32
+
+#define __NSIGSET_WORDS 1
+
+#define SIG_BLOCK 1
+#define SIG_UNBLOCK 2
+#define SIG_SETMASK 3
+
+#define SIG_ERR __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), -1)
+#define SIG_DFL __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 0)
+#define SIG_IGN __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 1)
+#define SIG_HOLD __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 5)
+
+#endif // LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/glob-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/glob-macros.h
new file mode 100644
index 00000000000..58965202734
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/glob-macros.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Macros for POSIX glob.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_GLOB_MACROS_H
+#define LLVM_LIBC_MACROS_GLOB_MACROS_H
+
+// Flags controlling glob() behavior.
+#define GLOB_ERR (1 << 0)
+#define GLOB_MARK (1 << 1)
+#define GLOB_NOSORT (1 << 2)
+#define GLOB_DOOFFS (1 << 3)
+#define GLOB_NOCHECK (1 << 4)
+#define GLOB_APPEND (1 << 5)
+#define GLOB_NOESCAPE (1 << 6)
+
+// glob() error return values.
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+
+#endif // LLVM_LIBC_MACROS_GLOB_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/limits-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/limits-macros.h
index 7a6b58e2d59..8a341e45e7c 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/limits-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/limits-macros.h
@@ -292,4 +292,8 @@
#endif
#endif
+#ifndef NZERO
+#define NZERO 20
+#endif // NZERO
+
#endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/CMakeLists.txt
index 7c1194d4dd1..5a032252d98 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -34,6 +34,12 @@ add_header(
sys-epoll-macros.h
)
+add_header(
+ sys_file_macros
+ HDR
+ sys-file-macros.h
+)
+
add_header(
sys_ioctl_macros
HDR
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/fcntl-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/fcntl-macros.h
index 8dcc177434c..648c4a9ec00 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -105,4 +105,12 @@
#define F_SETLKW F_SETLKW64
#endif
+// Advice values for posix_fadvise.
+#define POSIX_FADV_NORMAL 0
+#define POSIX_FADV_RANDOM 1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED 3
+#define POSIX_FADV_DONTNEED 4
+#define POSIX_FADV_NOREUSE 5
+
#endif // LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/netdb-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/netdb-macros.h
index 7bc06982f45..4965dbd18b3 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/netdb-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/netdb-macros.h
@@ -14,6 +14,14 @@
#ifndef LLVM_LIBC_MACROS_LINUX_NETDB_MACROS_H
#define LLVM_LIBC_MACROS_LINUX_NETDB_MACROS_H
+#define AI_PASSIVE 0x0001
+#define AI_CANONNAME 0x0002
+#define AI_NUMERICHOST 0x0004
+#define AI_V4MAPPED 0x0008
+#define AI_ALL 0x0010
+#define AI_ADDRCONFIG 0x0020
+#define AI_NUMERICSERV 0x0400
+
#define EAI_BADFLAGS -1
#define EAI_NONAME -2
#define EAI_AGAIN -3
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-file-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-file-macros.h
new file mode 100644
index 00000000000..20b17972d55
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-file-macros.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux specific declarations of macros from sys/file.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_FILE_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_FILE_MACROS_H
+
+#define LOCK_SH 1 // Shared lock.
+#define LOCK_EX 2 // Exclusive lock.
+#define LOCK_NB 4 // Flag to make a nonblocking request.
+#define LOCK_UN 8 // Remove an existing lock.
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_FILE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-resource-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-resource-macros.h
index 9f1e04a339c..4c3ebf39910 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-resource-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-resource-macros.h
@@ -34,4 +34,8 @@
#define RUSAGE_CHILDREN (-1)
#define RUSAGE_THREAD 1
+#define PRIO_PROCESS 0
+#define PRIO_PGRP 1
+#define PRIO_USER 2
+
#endif // LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/unistd-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/unistd-macros.h
index 49409f83711..9a0b8209d17 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/unistd-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/unistd-macros.h
@@ -23,12 +23,26 @@
#define _SC_ARG_MAX 0
#define _SC_CLK_TCK 2
#define _SC_OPEN_MAX 4
+#define _SC_VERSION 29
#define _SC_PAGESIZE 30
#define _SC_PAGE_SIZE _SC_PAGESIZE
#define _SC_THREADS 67
+#define _SC_THREAD_SAFE_FUNCTIONS 68
+#define _SC_GETGR_R_SIZE_MAX 69
+#define _SC_GETPW_R_SIZE_MAX 70
+#define _SC_THREAD_ATTR_STACKADDR 77
+#define _SC_THREAD_ATTR_STACKSIZE 78
+#define _SC_THREAD_PRIORITY_SCHEDULING 79
+#define _SC_THREAD_PRIO_INHERIT 80
+#define _SC_THREAD_PRIO_PROTECT 81
+#define _SC_THREAD_PROCESS_SHARED 82
#define _SC_NPROCESSORS_CONF 83
#define _SC_NPROCESSORS_ONLN 84
#define _SC_PHYS_PAGES 85
+#define _SC_THREAD_CPUTIME 139
+#define _SC_THREAD_SPORADIC_SERVER 161
+#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
#define _PC_FILESIZEBITS 0
#define _PC_LINK_MAX 1
@@ -53,11 +67,26 @@
// TODO: Move these limit macros to a separate file
#define _POSIX_CHOWN_RESTRICTED 1
-#define _POSIX_THREADS 202405L
#define _POSIX_PIPE_BUF 512
#define _POSIX_NO_TRUNC 1
#define _POSIX_VDISABLE '\0'
+#define _POSIX_VERSION 202405L
+
+// POSIX threads features.
+#define _POSIX_THREADS _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
+#define _POSIX_THREAD_CPUTIME -1
+#define _POSIX_THREAD_PRIO_INHERIT -1
+#define _POSIX_THREAD_PRIO_PROTECT -1
+#define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1
+#define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1
+#define _POSIX_THREAD_SPORADIC_SERVER -1
+
// Macro to set up the call to the __llvm_libc_syscall function
// This is to prevent the call from having fewer than 6 arguments, since six
// arguments are always passed to the syscall. Unnecessary arguments are
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/pthread-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/pthread-macros.h
index 58717200b5f..5f963054682 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/pthread-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/pthread-macros.h
@@ -29,6 +29,12 @@
#define PTHREAD_PROCESS_PRIVATE 0
#define PTHREAD_PROCESS_SHARED 1
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
#ifdef __linux__
#define PTHREAD_MUTEX_INITIALIZER \
{ \
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/signal-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/signal-macros.h
index 163c8742593..c28f668456f 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/signal-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/signal-macros.h
@@ -11,6 +11,8 @@
#if defined(__linux__)
#include "linux/signal-macros.h"
+#elif defined(__APPLE__)
+#include "darwin/signal-macros.h"
#elif defined(__NVPTX__) || defined(__AMDGPU__) || defined(__SPIRV__)
#include "gpu/signal-macros.h"
#endif
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-file-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-file-macros.h
new file mode 100644
index 00000000000..ba3123ed3d1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-file-macros.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Macros defined in sys/file.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_FILE_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_FILE_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-file-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_FILE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mman-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mman-macros.h
index bc9f783d84a..0dd5a86240d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mman-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mman-macros.h
@@ -28,6 +28,12 @@
#define MAP_FAILED ((void *)-1)
#endif
+// MAP_ANON is a synonym for MAP_ANONYMOUS specified in POSIX,
+// but is not always provided by kernel headers.
+#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
// Posix memory advise flags. (posix_madvise)
#ifndef POSIX_MADV_NORMAL
#define POSIX_MADV_NORMAL MADV_NORMAL
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/CMakeLists.txt
index 02b9adf88bc..cc7b4df1202 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/CMakeLists.txt
@@ -1,6 +1,40 @@
+# Helper function to set up dependencies if they exist.
+function(add_type_header name)
+ cmake_parse_arguments(
+ "TYPE_HEADER"
+ "" # Optional arguments
+ "HDR;DEST_HDR" # Single value arguments
+ "DEPENDS" # Multi-value arguments
+ ${ARGN}
+ )
+ if(TYPE_HEADER_DEST_HDR)
+ set(dest_header_arg DEST_HDR ${TYPE_HEADER_DEST_HDR})
+ endif()
+ set(deps)
+ if(TARGET libc.include.llvm-libc-types.${LIBC_TARGET_OS}.${name})
+ list(APPEND deps .${LIBC_TARGET_OS}.${name})
+ endif()
+ if(TARGET libc.include.llvm-libc-types.${LIBC_TARGET_ARCHITECTURE}.${name})
+ list(APPEND deps .${LIBC_TARGET_ARCHITECTURE}.${name})
+ endif()
+ if(TYPE_HEADER_DEPENDS)
+ list(APPEND deps ${TYPE_HEADER_DEPENDS})
+ endif()
+ add_header(
+ ${name}
+ HDR
+ ${TYPE_HEADER_HDR}
+ ${dest_header_arg}
+ DEPENDS
+ ${deps}
+ )
+endfunction()
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()
+
+add_header(off_t HDR off_t.h)
add_header(off64_t HDR off64_t.h)
add_header(size_t HDR size_t.h)
add_header(
@@ -35,7 +69,7 @@ add_header(cc_t HDR cc_t.h)
add_header(clock_t HDR clock_t.h)
add_header(clockid_t HDR clockid_t.h)
add_header(cnd_t HDR cnd_t.h DEPENDS .__futex_word)
-add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t .ssize_t)
+add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off_t .ssize_t)
add_header(cpu_set_t HDR cpu_set_t.h)
add_header(double_t HDR double_t.h)
add_header(DIR HDR DIR.h)
@@ -67,11 +101,11 @@ add_header(
)
add_header(ldiv_t HDR ldiv_t.h)
add_header(lldiv_t HDR lldiv_t.h)
-if(TARGET libc.include.llvm-libc-types.${LIBC_TARGET_OS}.loff_t)
- add_header(loff_t HDR loff_t.h DEPENDS .${LIBC_TARGET_OS}.loff_t)
-else()
- add_header(loff_t HDR loff_t.h)
-endif()
+add_type_header(
+ loff_t
+ HDR
+ loff_t.h
+)
add_header(FILE HDR FILE.h)
add_header(fd_set HDR fd_set.h DEPENDS libc.include.llvm-libc-macros.sys_select_macros)
add_header(fenv_t HDR fenv_t.h)
@@ -99,12 +133,12 @@ add_header(nfds_t HDR nfds_t.h)
add_header(nl_catd HDR nl_catd.h)
add_header(nl_item HDR nl_item.h)
add_header(nlink_t HDR nlink_t.h)
-add_header(off_t HDR off_t.h)
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
add_header(posix_spawn_file_actions_t HDR posix_spawn_file_actions_t.h)
add_header(posix_spawnattr_t HDR posix_spawnattr_t.h)
add_header(posix_tnode HDR posix_tnode.h)
-add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
+add_header(struct_sched_param HDR struct_sched_param.h)
+add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t .struct_sched_param)
add_header(pthread_cond_t HDR pthread_cond_t.h DEPENDS .__futex_word .size_t)
add_header(pthread_condattr_t HDR pthread_condattr_t.h DEPENDS .clockid_t)
add_header(pthread_key_t HDR pthread_key_t.h)
@@ -157,7 +191,6 @@ add_header(
)
add_header(struct_pollfd HDR struct_pollfd.h)
add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
-add_header(struct_sched_param HDR struct_sched_param.h)
add_header(struct_sembuf HDR struct_sembuf.h)
add_header(struct_seminfo HDR struct_seminfo.h)
add_header(
@@ -174,30 +207,6 @@ add_header(union_sigval HDR union_sigval.h)
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
add_header(sig_atomic_t HDR sig_atomic_t.h)
add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
-set(mcontext_deps)
-set(ucontext_deps .sigset_t .stack_t)
-
-if(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
- add_header(
- mcontext_t_arch
- HDR
- x86_64/mcontext_t.h
- )
- add_header(
- ucontext_t_arch
- HDR
- x86_64/ucontext_t.h
- DEPENDS
- .mcontext_t_arch
- .sigset_t
- .stack_t
- )
- list(APPEND mcontext_deps .mcontext_t_arch)
- list(APPEND ucontext_deps .ucontext_t_arch)
-endif()
-
-add_header(mcontext_t HDR mcontext_t.h DEPENDS ${mcontext_deps})
-add_header(ucontext_t HDR ucontext_t.h DEPENDS .mcontext_t ${ucontext_deps})
add_header(u_char HDR u_char.h)
add_header(u_int32_t HDR u_int32_t.h)
add_header(uint HDR uint.h)
@@ -218,11 +227,11 @@ add_header(
add_header(struct_tm HDR struct_tm.h)
add_header(struct_passwd HDR struct_passwd.h DEPENDS .uid_t .gid_t)
add_header(struct_group HDR struct_group.h DEPENDS .gid_t)
-if(TARGET libc.include.llvm-libc-types.${LIBC_TARGET_OS}.struct_sysinfo)
- add_header(struct_sysinfo HDR struct_sysinfo.h DEPENDS .${LIBC_TARGET_OS}.struct_sysinfo)
-else()
- add_header(struct_sysinfo HDR struct_sysinfo.h)
-endif()
+add_type_header(
+ struct_sysinfo
+ HDR
+ struct_sysinfo.h
+)
add_header(struct_utsname HDR struct_utsname.h)
add_header(thrd_start_t HDR thrd_start_t.h)
add_header(thrd_t HDR thrd_t.h DEPENDS .__thread_type)
@@ -299,6 +308,7 @@ add_header(ACTION HDR ACTION.h)
add_header(ENTRY HDR ENTRY.h)
add_header(VISIT HDR VISIT.h)
add_header(struct_hsearch_data HDR struct_hsearch_data.h)
+add_header(glob_t HDR glob_t.h DEPENDS .size_t)
add_header(regex_t HDR regex_t.h DEPENDS .size_t)
add_header(regoff_t HDR regoff_t.h)
add_header(regmatch_t HDR regmatch_t.h DEPENDS .regoff_t)
@@ -603,6 +613,15 @@ add_header(
.Elf64_Half
)
+# Arch-specific types
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+endif()
+
+add_type_header(mcontext_t HDR mcontext_t.h)
+add_type_header(ucontext_t HDR ucontext_t.h)
+add_type_header(struct_user_regs_struct HDR struct_user_regs_struct.h)
+
# UEFI
add_header(EFI_GUID HDR EFI_GUID.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
add_header(EFI_CONFIGURATION_TABLE HDR EFI_CONFIGURATION_TABLE.h DEPENDS .EFI_GUID)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/__jmp_buf.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/__jmp_buf.h
index a80afa2e6b8..266d2ffffa8 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/__jmp_buf.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/__jmp_buf.h
@@ -11,7 +11,7 @@
// TODO: implement sigjmp_buf related functions for other architectures
// Issue: https://github.com/llvm/llvm-project/issues/136358
-#if defined(__linux__)
+#if defined(__linux__) || defined(__APPLE__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
defined(__arm__) || defined(__riscv)
#define __LIBC_HAS_SIGJMP_BUF
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/char8_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/char8_t.h
index a343be77d81..6c121276017 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/char8_t.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/char8_t.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_TYPES_CHAR8_T_H
#define LLVM_LIBC_TYPES_CHAR8_T_H
-#if !(defined(__cplusplus) && defined(__cpp_char8_t))
+#ifndef __cpp_char8_t
typedef unsigned char char8_t;
-#endif
+#endif // !__cpp_char8_t
#endif // LLVM_LIBC_TYPES_CHAR8_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/cookie_io_functions_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/cookie_io_functions_t.h
index d1eea8ff3b5..27ad107c486 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/cookie_io_functions_t.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/cookie_io_functions_t.h
@@ -9,13 +9,13 @@
#ifndef LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
#define LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
-#include "off64_t.h"
+#include "off_t.h"
#include "size_t.h"
#include "ssize_t.h"
typedef ssize_t cookie_read_function_t(void *, char *, size_t);
typedef ssize_t cookie_write_function_t(void *, const char *, size_t);
-typedef int cookie_seek_function_t(void *, off64_t *, int);
+typedef int cookie_seek_function_t(void *, off_t *, int);
typedef int cookie_close_function_t(void *);
typedef struct {
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fenv_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fenv_t.h
index 2cfeff7b8a9..f9b10762a02 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fenv_t.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fenv_t.h
@@ -10,10 +10,17 @@
#define LLVM_LIBC_TYPES_FENV_T_H
#ifdef __aarch64__
+#ifdef __APPLE__
+typedef struct {
+ unsigned long long __fpsr;
+ unsigned long long __fpcr;
+} fenv_t;
+#else
typedef struct {
unsigned char __control_word[4];
unsigned char __status_word[4];
} fenv_t;
+#endif
#elif defined(__x86_64__)
typedef struct {
unsigned char __x86_status[28];
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/glob_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/glob_t.h
new file mode 100644
index 00000000000..811de9cab10
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/glob_t.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Type definition for glob_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_GLOB_T_H
+#define LLVM_LIBC_TYPES_GLOB_T_H
+
+#include "size_t.h"
+
+typedef struct {
+ size_t gl_pathc; // Count of paths matched by pattern.
+ char **gl_pathv; // Pointer to a list of matched pathnames.
+ size_t gl_offs; // Slots to reserve at the beginning of gl_pathv.
+} glob_t;
+
+#endif // LLVM_LIBC_TYPES_GLOB_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/pthread_attr_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/pthread_attr_t.h
index e686ac91a6f..0e5fa228e6a 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/pthread_attr_t.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/pthread_attr_t.h
@@ -10,9 +10,13 @@
#define LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
#include "size_t.h"
+#include "struct_sched_param.h"
typedef struct {
int __detachstate;
+ int __inheritsched;
+ int __schedpolicy;
+ struct sched_param __schedparam;
void *__stack;
size_t __stacksize;
size_t __guardsize;
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_user_regs_struct.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_user_regs_struct.h
new file mode 100644
index 00000000000..a8a0fd7356d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_user_regs_struct.h
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of type struct user_regs_struct.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_USER_REGS_STRUCT_H
+#define LLVM_LIBC_TYPES_STRUCT_USER_REGS_STRUCT_H
+
+#if defined(__x86_64__)
+#include "x86_64/struct_user_regs_struct.h"
+#else
+#error "struct user_regs_struct not available for your target architecture."
+#endif
+
+#endif // LLVM_LIBC_TYPES_STRUCT_USER_REGS_STRUCT_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/CMakeLists.txt
new file mode 100644
index 00000000000..ec5202f9881
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_header(
+ mcontext_t
+ HDR
+ mcontext_t.h
+)
+
+add_header(
+ struct_user_regs_struct
+ HDR
+ struct_user_regs_struct.h
+)
+
+add_header(
+ ucontext_t
+ HDR
+ ucontext_t.h
+ DEPENDS
+ .mcontext_t
+ libc.include.llvm-libc-types.sigset_t
+ libc.include.llvm-libc-types.stack_t
+)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/struct_user_regs_struct.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/struct_user_regs_struct.h
new file mode 100644
index 00000000000..4a95ed44889
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/x86_64/struct_user_regs_struct.h
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Definition of struct user_regs_struct for x86_64.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_X86_64_STRUCT_USER_REGS_STRUCT_H
+#define LLVM_LIBC_TYPES_X86_64_STRUCT_USER_REGS_STRUCT_H
+
+struct user_regs_struct {
+ unsigned long long r15;
+ unsigned long long r14;
+ unsigned long long r13;
+ unsigned long long r12;
+ unsigned long long rbp;
+ unsigned long long rbx;
+ unsigned long long r11;
+ unsigned long long r10;
+ unsigned long long r9;
+ unsigned long long r8;
+ unsigned long long rax;
+ unsigned long long rcx;
+ unsigned long long rdx;
+ unsigned long long rsi;
+ unsigned long long rdi;
+ unsigned long long orig_rax;
+ unsigned long long rip;
+ unsigned long long cs;
+ unsigned long long eflags;
+ unsigned long long rsp;
+ unsigned long long ss;
+ unsigned long long fs_base;
+ unsigned long long gs_base;
+ unsigned long long ds;
+ unsigned long long es;
+ unsigned long long fs;
+ unsigned long long gs;
+};
+
+#endif // LLVM_LIBC_TYPES_X86_64_STRUCT_USER_REGS_STRUCT_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/netdb.yaml b/deps/v8/third_party/llvm-libc/src/include/netdb.yaml
index b98f30fd1a2..84e6827abd8 100644
--- a/deps/v8/third_party/llvm-libc/src/include/netdb.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/netdb.yaml
@@ -2,6 +2,20 @@ header: netdb.h
standards:
- posix
macros:
+ - macro_name: AI_PASSIVE
+ macro_header: netdb-macros.h
+ - macro_name: AI_CANONNAME
+ macro_header: netdb-macros.h
+ - macro_name: AI_NUMERICHOST
+ macro_header: netdb-macros.h
+ - macro_name: AI_NUMERICSERV
+ macro_header: netdb-macros.h
+ - macro_name: AI_V4MAPPED
+ macro_header: netdb-macros.h
+ - macro_name: AI_ALL
+ macro_header: netdb-macros.h
+ - macro_name: AI_ADDRCONFIG
+ macro_header: netdb-macros.h
- macro_name: EAI_AGAIN
macro_header: netdb-macros.h
- macro_name: EAI_BADFLAGS
@@ -33,6 +47,12 @@ functions:
return_type: void
arguments:
- type: struct addrinfo *
+ - name: gai_strerror
+ standards:
+ - posix
+ return_type: const char *
+ arguments:
+ - type: int
- name: getaddrinfo
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/pthread.yaml b/deps/v8/third_party/llvm-libc/src/include/pthread.yaml
index 784b1c207b9..875dec99f7f 100644
--- a/deps/v8/third_party/llvm-libc/src/include/pthread.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/pthread.yaml
@@ -28,6 +28,14 @@ macros:
macro_header: pthread-macros.h
- macro_name: "PTHREAD_PROCESS_SHARED"
macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_SCOPE_SYSTEM"
+ macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_SCOPE_PROCESS"
+ macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_INHERIT_SCHED"
+ macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_EXPLICIT_SCHED"
+ macro_header: pthread-macros.h
- macro_name: "PTHREAD_MUTEX_INITIALIZER"
macro_header: pthread-macros.h
- macro_name: "PTHREAD_COND_INITIALIZER"
@@ -92,11 +100,30 @@ functions:
arguments:
- type: const pthread_attr_t *__restrict
- type: size_t *__restrict
+ - name: pthread_attr_getinheritsched
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const pthread_attr_t *__restrict
+ - type: int *__restrict
- name: pthread_attr_getschedparam
return_type: int
arguments:
- type: const pthread_attr_t *__restrict
- type: struct sched_param *__restrict
+ - name: pthread_attr_getschedpolicy
+ return_type: int
+ arguments:
+ - type: const pthread_attr_t *__restrict
+ - type: int *__restrict
+ - name: pthread_attr_getscope
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const pthread_attr_t *__restrict
+ - type: int *__restrict
- name: pthread_attr_getstack
return_type: int
arguments:
@@ -122,11 +149,30 @@ functions:
arguments:
- type: pthread_attr_t *
- type: size_t
+ - name: pthread_attr_setinheritsched
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: pthread_attr_t *
+ - type: int
- name: pthread_attr_setschedparam
return_type: int
arguments:
- type: pthread_attr_t *__restrict
- type: const struct sched_param *__restrict
+ - name: pthread_attr_setschedpolicy
+ return_type: int
+ arguments:
+ - type: pthread_attr_t *
+ - type: int
+ - name: pthread_attr_setscope
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: pthread_attr_t *
+ - type: int
- name: pthread_attr_setstack
return_type: int
arguments:
diff --git a/deps/v8/third_party/llvm-libc/src/include/pwd.yaml b/deps/v8/third_party/llvm-libc/src/include/pwd.yaml
index 40db5690e98..9301307d22d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/pwd.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/pwd.yaml
@@ -24,3 +24,35 @@ functions:
- posix
return_type: void
arguments: []
+ - name: getpwnam
+ standards:
+ - posix
+ return_type: struct passwd *
+ arguments:
+ - type: const char *
+ - name: getpwnam_r
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: struct passwd *
+ - type: char *
+ - type: size_t
+ - type: struct passwd **
+ - name: getpwuid
+ standards:
+ - posix
+ return_type: struct passwd *
+ arguments:
+ - type: uid_t
+ - name: getpwuid_r
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: uid_t
+ - type: struct passwd *
+ - type: char *
+ - type: size_t
+ - type: struct passwd **
diff --git a/deps/v8/third_party/llvm-libc/src/include/signal.yaml b/deps/v8/third_party/llvm-libc/src/include/signal.yaml
index 88c931edd51..f5f110915cf 100644
--- a/deps/v8/third_party/llvm-libc/src/include/signal.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/signal.yaml
@@ -43,6 +43,9 @@ types:
- type_name: struct_sigaction
- type_name: struct_sigevent
- type_name: union_sigval
+ - type_name: pthread_t
+ standards:
+ - posix
enums: []
objects: []
functions:
@@ -128,3 +131,10 @@ functions:
- type: int
- type: const sigset_t *__restrict
- type: sigset_t *__restrict
+ - name: pthread_kill
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: pthread_t
+ - type: int
diff --git a/deps/v8/third_party/llvm-libc/src/include/stdfix.yaml b/deps/v8/third_party/llvm-libc/src/include/stdfix.yaml
index f91e4ea620e..739805ea2a3 100644
--- a/deps/v8/third_party/llvm-libc/src/include/stdfix.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/stdfix.yaml
@@ -565,6 +565,62 @@ functions:
- type: int
- type: int
guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: lrdivi
+ standards:
+ - stdc_ext
+ return_type: long fract
+ arguments:
+ - type: long int
+ - type: long int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: kdivi
+ standards:
+ - stdc_ext
+ return_type: accum
+ arguments:
+ - type: int
+ - type: int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: lkdivi
+ standards:
+ - stdc_ext
+ return_type: long accum
+ arguments:
+ - type: long int
+ - type: long int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: urdivi
+ standards:
+ - stdc_ext
+ return_type: unsigned fract
+ arguments:
+ - type: unsigned int
+ - type: unsigned int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: ulrdivi
+ standards:
+ - stdc_ext
+ return_type: unsigned long fract
+ arguments:
+ - type: unsigned long int
+ - type: unsigned long int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: ukdivi
+ standards:
+ - stdc_ext
+ return_type: unsigned accum
+ arguments:
+ - type: unsigned int
+ - type: unsigned int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: ulkdivi
+ standards:
+ - stdc_ext
+ return_type: unsigned long accum
+ arguments:
+ - type: unsigned long int
+ - type: unsigned long int
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: divir
standards:
- stdc_ext
diff --git a/deps/v8/third_party/llvm-libc/src/include/stdio.yaml b/deps/v8/third_party/llvm-libc/src/include/stdio.yaml
index ef725dd4fe6..bb28dadd29b 100644
--- a/deps/v8/third_party/llvm-libc/src/include/stdio.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/stdio.yaml
@@ -139,6 +139,14 @@ functions:
return_type: void
arguments:
- type: FILE *
+ - name: fmemopen
+ standards:
+ - posix
+ return_type: FILE *
+ arguments:
+ - type: void *__restrict
+ - type: size_t
+ - type: const char *__restrict
- name: fopen
standards:
- stdc
diff --git a/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml b/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml
index efbd4702919..aabb9dd106a 100644
--- a/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml
@@ -116,6 +116,13 @@ functions:
return_type: char *
arguments:
- type: const char *
+ - name: getloadavg
+ standards:
+ - bsd
+ return_type: int
+ arguments:
+ - type: double[]
+ - type: int
- name: labs
standards:
- stdc
@@ -171,6 +178,19 @@ functions:
return_type: size_t
arguments:
- type: const void *
+ - name: mkdtemp
+ standards:
+ - posix
+ return_type: char *
+ arguments:
+ - type: char *
+ - name: mkostemp
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: char *
+ - type: int
- name: mkstemp
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/file.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/file.yaml
new file mode 100644
index 00000000000..a1a52f5e093
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/file.yaml
@@ -0,0 +1,23 @@
+header: sys/file.h
+standards:
+ - bsd
+macros:
+ - macro_name: LOCK_SH
+ macro_header: sys-file-macros.h
+ - macro_name: LOCK_EX
+ macro_header: sys-file-macros.h
+ - macro_name: LOCK_NB
+ macro_header: sys-file-macros.h
+ - macro_name: LOCK_UN
+ macro_header: sys-file-macros.h
+types: []
+enums: []
+objects: []
+functions:
+ - name: flock
+ standards:
+ - bsd
+ return_type: int
+ arguments:
+ - type: int
+ - type: int
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/mman.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/mman.yaml
index 04509f4aabf..bbd3ebaf72d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/mman.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/mman.yaml
@@ -2,6 +2,8 @@ header: sys/mman.h
standards:
- posix
macros:
+ - macro_name: MAP_ANON
+ macro_header: sys-mman-macros.h
- macro_name: MAP_FAILED
macro_header: sys-mman-macros.h
types:
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/resource.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/resource.yaml
index a26dfb5f77b..c4733dead75 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/resource.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/resource.yaml
@@ -12,6 +12,12 @@ macros:
macro_header: sys-resource-macros.h
standards:
- gnu
+ - macro_name: PRIO_PROCESS
+ macro_header: sys-resource-macros.h
+ - macro_name: PRIO_PGRP
+ macro_header: sys-resource-macros.h
+ - macro_name: PRIO_USER
+ macro_header: sys-resource-macros.h
types:
- type_name: struct_rlimit
- type_name: rlim_t
@@ -19,6 +25,13 @@ types:
enums: []
objects: []
functions:
+ - name: getpriority
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
+ - type: id_t
- name: getrlimit
standards:
- posix
@@ -33,6 +46,14 @@ functions:
arguments:
- type: int
- type: struct rusage *
+ - name: setpriority
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
+ - type: id_t
+ - type: int
- name: setrlimit
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/stat.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/stat.yaml
index 5c033f621f1..3c75ce3d796 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/stat.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/stat.yaml
@@ -58,11 +58,20 @@ functions:
- type: int
- type: const char *
- type: mode_t
+ - name: mkfifo
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: mode_t
- name: stat
return_type: int
arguments:
- type: const char *__restrict
- type: struct stat *__restrict
+ - name: umask
+ return_type: mode_t
+ arguments:
+ - type: mode_t
- name: utimensat
return_type: int
arguments:
@@ -70,3 +79,8 @@ functions:
- type: const char *
- type: const struct timespec *
- type: int
+ - name: futimens
+ return_type: int
+ arguments:
+ - type: int
+ - type: const struct timespec *
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/user.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/user.yaml
new file mode 100644
index 00000000000..8f3d209cfd8
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/user.yaml
@@ -0,0 +1,5 @@
+header: sys/user.h
+standards:
+ - linux
+types:
+ - type_name: struct_user_regs_struct
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/xattr.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/xattr.yaml
new file mode 100644
index 00000000000..5f8b6174af0
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/xattr.yaml
@@ -0,0 +1,34 @@
+header: sys/xattr.h
+standards:
+ - linux
+macros: []
+types:
+ - type_name: size_t
+ - type_name: ssize_t
+enums: []
+objects: []
+functions:
+ - name: listxattr
+ standards:
+ - linux
+ return_type: ssize_t
+ arguments:
+ - type: const char *
+ - type: char *
+ - type: size_t
+ - name: llistxattr
+ standards:
+ - linux
+ return_type: ssize_t
+ arguments:
+ - type: const char *
+ - type: char *
+ - type: size_t
+ - name: flistxattr
+ standards:
+ - linux
+ return_type: ssize_t
+ arguments:
+ - type: int
+ - type: char *
+ - type: size_t
diff --git a/deps/v8/third_party/llvm-libc/src/include/unistd.yaml b/deps/v8/third_party/llvm-libc/src/include/unistd.yaml
index d6c0235dd83..890a4ae21f1 100644
--- a/deps/v8/third_party/llvm-libc/src/include/unistd.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/unistd.yaml
@@ -20,20 +20,72 @@ macros:
macro_header: unistd-macros.h
- macro_name: _SC_OPEN_MAX
macro_header: unistd-macros.h
+ - macro_name: _SC_VERSION
+ macro_header: unistd-macros.h
- macro_name: _SC_PAGESIZE
macro_header: unistd-macros.h
- macro_name: _SC_PAGE_SIZE
macro_header: unistd-macros.h
- macro_name: _SC_THREADS
macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_SAFE_FUNCTIONS
+ macro_header: unistd-macros.h
+ - macro_name: _SC_GETGR_R_SIZE_MAX
+ macro_header: unistd-macros.h
+ - macro_name: _SC_GETPW_R_SIZE_MAX
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_ATTR_STACKADDR
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_ATTR_STACKSIZE
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_PRIORITY_SCHEDULING
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_PRIO_INHERIT
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_PRIO_PROTECT
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_PROCESS_SHARED
+ macro_header: unistd-macros.h
- macro_name: _SC_NPROCESSORS_CONF
macro_header: unistd-macros.h
- macro_name: _SC_NPROCESSORS_ONLN
macro_header: unistd-macros.h
- macro_name: _SC_PHYS_PAGES
macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_CPUTIME
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_SPORADIC_SERVER
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_ROBUST_PRIO_INHERIT
+ macro_header: unistd-macros.h
+ - macro_name: _SC_THREAD_ROBUST_PRIO_PROTECT
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_VERSION
+ macro_header: unistd-macros.h
- macro_name: _POSIX_THREADS
macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_SAFE_FUNCTIONS
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_ATTR_STACKADDR
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_ATTR_STACKSIZE
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_PROCESS_SHARED
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_PRIORITY_SCHEDULING
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_CPUTIME
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_PRIO_INHERIT
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_PRIO_PROTECT
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_ROBUST_PRIO_INHERIT
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_ROBUST_PRIO_PROTECT
+ macro_header: unistd-macros.h
+ - macro_name: _POSIX_THREAD_SPORADIC_SERVER
+ macro_header: unistd-macros.h
types:
- type_name: uid_t
- type_name: gid_t
@@ -103,6 +155,12 @@ functions:
- type: const char *
- type: uid_t
- type: gid_t
+ - name: chroot
+ standards:
+ - gnu
+ return_type: int
+ arguments:
+ - type: const char *
- name: confstr
standards:
- posix
@@ -138,6 +196,14 @@ functions:
- type: int
- type: int
- type: int
+ - name: execl
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - type: '...'
- name: execle
standards:
- posix
@@ -217,6 +283,12 @@ functions:
arguments:
- type: char *
- type: size_t
+ - name: getegid
+ standards:
+ - posix
+ return_type: gid_t
+ arguments:
+ - type: void
- name: getentropy
standards:
- gnu
@@ -251,6 +323,18 @@ functions:
- type: int
- type: __getoptargv_t
- type: const char *
+ - name: getpgid
+ standards:
+ - posix
+ return_type: pid_t
+ arguments:
+ - type: pid_t
+ - name: getpgrp
+ standards:
+ - posix
+ return_type: pid_t
+ arguments:
+ - type: void
- name: getpid
standards:
- posix
@@ -320,6 +404,12 @@ functions:
- type: int
- type: off_t
- type: int
+ - name: nice
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
- name: pathconf
standards:
- posix
@@ -397,12 +487,45 @@ functions:
- type: const void *__restrict
- type: void *
- type: ssize_t
+ - name: setgid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: gid_t
+ - name: setpgid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: pid_t
+ - type: pid_t
+ - name: setregid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: gid_t
+ - type: gid_t
+ - name: setreuid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: uid_t
+ - type: uid_t
- name: setsid
standards:
- posix
return_type: pid_t
arguments:
- type: void
+ - name: setuid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: uid_t
- name: sleep
standards:
- posix
@@ -430,6 +553,19 @@ functions:
return_type: long
arguments:
- type: int
+ - name: tcgetpgrp
+ standards:
+ - posix
+ return_type: pid_t
+ arguments:
+ - type: int
+ - name: tcsetpgrp
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
+ - type: pid_t
- name: truncate
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/wchar.yaml b/deps/v8/third_party/llvm-libc/src/include/wchar.yaml
index 1017eb827cf..2b321f6502f 100644
--- a/deps/v8/third_party/llvm-libc/src/include/wchar.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/wchar.yaml
@@ -117,6 +117,21 @@ functions:
arguments:
- type: const wchar_t *
- type: const wchar_t *
+ - name: wcscasecmp
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const wchar_t *
+ - type: const wchar_t *
+ - name: wcsncasecmp
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const wchar_t *
+ - type: const wchar_t *
+ - type: size_t
- name: wcscoll
standards:
- stdc
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/copysignf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/copysignf128.h
index 1b23f61f910..b6e156b96af 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/copysignf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/copysignf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_COPYSIGNF128_H
#define LLVM_LIBC_SHARED_MATH_COPYSIGNF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/copysignf128.h"
@@ -24,6 +20,4 @@ using math::copysignf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_COPYSIGNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fabsf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fabsf128.h
index 88e4d036868..037553bcb97 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fabsf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fabsf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FABSF128_H
#define LLVM_LIBC_SHARED_MATH_FABSF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fabsf128.h"
@@ -24,6 +20,4 @@ using math::fabsf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FABSF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fdimf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fdimf128.h
index 0cac3ce9a67..16437f3bc00 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fdimf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fdimf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FDIMF128_H
#define LLVM_LIBC_SHARED_MATH_FDIMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fdimf128.h"
@@ -24,6 +20,4 @@ using math::fdimf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FDIMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_mag_numf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_mag_numf128.h
index de2d21e4244..d12909fbc47 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_mag_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_mag_numf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAG_NUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAG_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_mag_numf128.h"
@@ -24,6 +20,4 @@ using math::fmaximum_mag_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAG_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_magf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_magf128.h
index 93996933d10..88794875893 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_magf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_magf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAGF128_H
#define LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_magf128.h"
@@ -24,6 +20,4 @@ using math::fmaximum_magf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMAXIMUM_MAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_numf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_numf128.h
index f26724d537a..50557e8d25a 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximum_numf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMAXIMUM_NUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMAXIMUM_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_numf128.h"
@@ -24,6 +20,4 @@ using math::fmaximum_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMAXIMUM_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximumf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximumf128.h
index 12b53d74e4f..af6beefbb99 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmaximumf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmaximumf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMAXIMUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMAXIMUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fmaximumf128.h"
@@ -24,6 +20,4 @@ using math::fmaximumf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMAXIMUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_mag_numf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_mag_numf128.h
index 416a9c610bf..75e04f510f7 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_mag_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_mag_numf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMINIMUM_MAG_NUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMINIMUM_MAG_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_mag_numf128.h"
@@ -24,6 +20,4 @@ using math::fminimum_mag_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMINIMUM_MAG_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_magf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_magf128.h
index cf8794c5b16..f538605febf 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_magf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_magf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMINIMUM_MAGF128_H
#define LLVM_LIBC_SHARED_MATH_FMINIMUM_MAGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_magf128.h"
@@ -24,6 +20,4 @@ using math::fminimum_magf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMINIMUM_MAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_numf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_numf128.h
index dcacd52b18a..e654f0025bd 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fminimum_numf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMINIMUM_NUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMINIMUM_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_numf128.h"
@@ -24,6 +20,4 @@ using math::fminimum_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMINIMUM_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fminimumf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fminimumf128.h
index 1f31c05d73c..2604222a7e7 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fminimumf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fminimumf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMINIMUMF128_H
#define LLVM_LIBC_SHARED_MATH_FMINIMUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fminimumf128.h"
@@ -24,6 +20,4 @@ using math::fminimumf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMINIMUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/rpc.h b/deps/v8/third_party/llvm-libc/src/shared/rpc.h
index bd55bc34870..c4a96bf3389 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/rpc.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/rpc.h
@@ -237,47 +237,18 @@ template <bool Invert> struct Process {
return Invert ? !cond : cond;
}
- /// Attempt to claim the lock at index. Return true on lock taken.
- /// lane_mask is a bitmap of the threads in the warp that would hold the
- /// single lock on success, e.g. the result of rpc::get_lane_mask()
- /// The lock is held when the n-th bit of the lock bitfield is set.
+ /// Attempts to claim the lock at this index under the given execution mask.
+ /// Returns true on success.
RPC_ATTRS bool try_lock(uint64_t lane_mask, uint32_t index) {
- // On AMDGPU, test and set to the n-th lock bit and a sync_lane would
- // suffice On NVIDIA with ITS we need to handle differences between the
- // threads running and the threads that were detected in the previous call
- // to get_lane_mask()
- //
- // All threads in lane_mask try to claim the lock. At most one can succeed.
- // There may be threads active which are not in lane mask which must not
- // succeed in taking the lock, as otherwise it will leak. This is handled
- // by making threads which are not in lane_mask or with 0, a no-op.
- uint32_t id = rpc::get_lane_id();
- bool id_in_lane_mask = lane_mask & (1ul << id);
-
- // All threads in the warp call fetch_or. Possibly at the same time.
- bool before = set_nth(lock, index, id_in_lane_mask);
- uint64_t packed = rpc::ballot(lane_mask, before);
-
- // If every bit set in lane_mask is also set in packed, every single thread
- // in the warp failed to get the lock. Ballot returns unset for threads not
- // in the lane mask.
- //
- // Cases, per thread:
- // mask==0 -> unspecified before, discarded by ballot -> 0
- // mask==1 and before==0 (success), set zero by ballot -> 0
- // mask==1 and before==1 (failure), set one by ballot -> 1
- //
- // mask != packed implies at least one of the threads got the lock
- // atomic semantics of fetch_or mean at most one of the threads for the lock
-
- // If holding the lock then the caller can load values knowing said loads
- // won't move past the lock. No such guarantee is needed if the lock acquire
- // failed. This conditional branch is expected to fold in the caller after
- // inlining the current function.
- bool holding_lock = lane_mask != packed;
- if (holding_lock)
+ bool claimed = false;
+ if (rpc::is_first_lane(lane_mask))
+ claimed = !set_nth(lock, index);
+ claimed = rpc::broadcast_value(lane_mask, claimed);
+
+ // Do not move any reads past the point we obtain the lock.
+ if (claimed)
__scoped_atomic_thread_fence(__ATOMIC_ACQUIRE, __MEMORY_SCOPE_DEVICE);
- return holding_lock;
+ return claimed;
}
/// Unlock the lock at index. We need a lane sync to keep this function
@@ -286,11 +257,8 @@ template <bool Invert> struct Process {
// Do not move any writes past the unlock.
__scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_DEVICE);
- // Use exactly one thread to clear the nth bit in the lock array Must
- // restrict to a single thread to avoid one thread dropping the lock, then
- // an unrelated warp claiming the lock, then a second thread in this warp
- // dropping the lock again.
- clear_nth(lock, index, rpc::is_first_lane(lane_mask));
+ if (rpc::is_first_lane(lane_mask))
+ clear_nth(lock, index);
rpc::sync_lane(lane_mask);
}
@@ -331,23 +299,20 @@ template <bool Invert> struct Process {
}
/// Conditionally set the n-th bit in the atomic bitfield.
- RPC_ATTRS static constexpr uint32_t set_nth(uint32_t *bits, uint32_t index,
- bool cond) {
+ RPC_ATTRS static constexpr uint32_t set_nth(uint32_t *bits, uint32_t index) {
uint32_t slot = index / NUM_BITS_IN_WORD;
uint32_t bit = index % NUM_BITS_IN_WORD;
- return __scoped_atomic_fetch_or(&bits[slot],
- static_cast<uint32_t>(cond) << bit,
- __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE) &
+ return __scoped_atomic_fetch_or(&bits[slot], 1u << bit, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_DEVICE) &
(1u << bit);
}
/// Conditionally clear the n-th bit in the atomic bitfield.
- RPC_ATTRS static constexpr uint32_t clear_nth(uint32_t *bits, uint32_t index,
- bool cond) {
+ RPC_ATTRS static constexpr uint32_t clear_nth(uint32_t *bits,
+ uint32_t index) {
uint32_t slot = index / NUM_BITS_IN_WORD;
uint32_t bit = index % NUM_BITS_IN_WORD;
- return __scoped_atomic_fetch_and(&bits[slot],
- ~0u ^ (static_cast<uint32_t>(cond) << bit),
+ return __scoped_atomic_fetch_and(&bits[slot], ~0u ^ (1u << bit),
__ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE) &
(1u << bit);
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/CMakeLists.txt
index 897a4c63e60..f6d998fee2e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CMakeLists.txt
@@ -392,6 +392,17 @@ add_header_library(
frac128.h
DEPENDS
.big_int
+ .frac64
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ frac256
+ HDRS
+ frac256.h
+ DEPENDS
+ .big_int
+ .frac128
libc.src.__support.macros.config
)
@@ -493,6 +504,7 @@ add_subdirectory(net)
add_subdirectory(threads)
add_subdirectory(File)
+add_subdirectory(pwd)
add_subdirectory(printf_core)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/CMakeLists.txt
index 8256caebfe7..16d9db567ab 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/CMakeLists.txt
@@ -195,6 +195,9 @@ add_header_library(
utility/in_place.h
utility/integer_sequence.h
utility/move.h
+ utility/swap.h
+ DEPENDS
+ libc.hdr.types.size_t
)
add_header_library(
@@ -250,3 +253,20 @@ add_header_library(
.utility
.tuple
)
+
+add_header_library(
+ vector
+ HDRS
+ vector.h
+ DEPENDS
+ .new
+ .type_traits
+ .utility
+ libc.hdr.func.free
+ libc.hdr.func.malloc
+ libc.hdr.func.realloc
+ libc.hdr.types.size_t
+ libc.src.__support.common
+ libc.src.__support.libc_assert
+ libc.src.__support.macros.config
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/algorithm.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/algorithm.h
index 3e2ac8b7b95..20ec1e85c67 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/algorithm.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/algorithm.h
@@ -1,12 +1,14 @@
-//===-- A self contained equivalent of <algorithm> --------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-// This file is minimalist on purpose but can receive a few more function if
-// they prove useful.
+///
+/// \file
+/// Implementation of algorithms analogous to <algorithm>.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_ALGORITHM_H
@@ -32,6 +34,17 @@ template <class T> LIBC_INLINE constexpr const T &min(const T &a, const T &b) {
return (a < b) ? a : b;
}
+template <class T>
+LIBC_INLINE constexpr const T &clamp(const T &v, const T &lo, const T &hi) {
+ return (v < lo) ? lo : (hi < v) ? hi : v;
+}
+
+template <class T, class Compare>
+LIBC_INLINE constexpr const T &clamp(const T &v, const T &lo, const T &hi,
+ Compare comp) {
+ return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
+}
+
template <class T> LIBC_INLINE constexpr T abs(T a) { return a < 0 ? -a : a; }
template <class InputIt, class UnaryPred>
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/span.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/span.h
index 9234a26d201..859ba24d144 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/span.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/span.h
@@ -1,10 +1,15 @@
-//===-- Standalone implementation std::span ---------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of cpp::span.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_SPAN_H
@@ -55,6 +60,7 @@ public:
LIBC_INLINE constexpr span() : span_data(nullptr), span_size(0) {}
LIBC_INLINE constexpr span(const span &) = default;
+ LIBC_INLINE constexpr span &operator=(const span &) = default;
LIBC_INLINE constexpr span(pointer first, size_type count)
: span_data(first), span_size(count) {}
@@ -72,11 +78,11 @@ public:
: span_data(arr.data()), span_size(arr.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- LIBC_INLINE constexpr span(span<U> &s)
+ LIBC_INLINE constexpr span(const span<U> &s)
: span_data(s.data()), span_size(s.size()) {}
template <typename U, cpp::enable_if_t<is_compatible_v<U>, bool> = true>
- LIBC_INLINE constexpr span &operator=(span<U> &s) {
+ LIBC_INLINE constexpr span &operator=(const span<U> &s) {
span_data = s.data();
span_size = s.size();
return *this;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility.h
index 083b4877c39..ac28c811b5a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility.h
@@ -1,10 +1,15 @@
-//===-- Analogous to <utility> ----------------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Header for <utility> analogues.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_H
@@ -14,5 +19,6 @@
#include "src/__support/CPP/utility/in_place.h"
#include "src/__support/CPP/utility/integer_sequence.h"
#include "src/__support/CPP/utility/move.h"
+#include "src/__support/CPP/utility/swap.h"
#endif // LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility/swap.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility/swap.h
new file mode 100644
index 00000000000..496c0f63369
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/utility/swap.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of the swap utility.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_SWAP_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_SWAP_H
+
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/utility/move.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace cpp {
+
+template <class T> LIBC_INLINE constexpr void swap(T &a, T &b) {
+ T temp = cpp::move(a);
+ a = cpp::move(b);
+ b = cpp::move(temp);
+}
+
+template <class T, size_t N>
+LIBC_INLINE constexpr void swap(T (&a)[N], T (&b)[N]) {
+ for (size_t i = 0; i < N; ++i)
+ swap(a[i], b[i]);
+}
+
+} // namespace cpp
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_CPP_UTILITY_SWAP_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/vector.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/vector.h
new file mode 100644
index 00000000000..839a9375056
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/vector.h
@@ -0,0 +1,309 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of vector container.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
+
+#include "hdr/func/free.h"
+#include "hdr/func/malloc.h"
+#include "hdr/func/realloc.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/CPP/utility.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_assert.h"
+#include "src/__support/macros/config.h"
+
+#include <stddef.h> // For max_align_t, ptrdiff_t
+
+namespace LIBC_NAMESPACE_DECL {
+namespace cpp {
+
+template <typename T> class vector {
+ static_assert(alignof(T) <= alignof(max_align_t),
+ "Overaligned types are not supported by cpp::vector");
+
+public:
+ using value_type = T;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using reference = T &;
+ using const_reference = const T &;
+ using pointer = T *;
+ using const_pointer = const T *;
+ using iterator = T *;
+ using const_iterator = const T *;
+
+ [[nodiscard]] LIBC_INLINE constexpr size_type max_size() const noexcept {
+ return static_cast<size_type>(-1) / sizeof(T);
+ }
+
+private:
+ T *data_ = nullptr;
+ size_t size_ = 0;
+ size_t capacity_ = 0;
+
+ static constexpr size_t DEFAULT_INITIAL_CAPACITY = 16;
+
+ LIBC_INLINE void destroy_elements(size_t from, size_t to) {
+ if constexpr (!is_trivially_destructible_v<T>) {
+ while (to > from) {
+ --to;
+ data_[to].~T();
+ }
+ }
+ }
+
+ LIBC_INLINE void deallocate() {
+ if (data_) {
+ destroy_elements(0, size_);
+ ::free(data_);
+ data_ = nullptr;
+ size_ = 0;
+ capacity_ = 0;
+ }
+ }
+
+ [[nodiscard]] LIBC_INLINE bool reallocate(size_t new_cap) {
+ if constexpr (is_trivially_copyable_v<T>) {
+ void *new_data = ::realloc(data_, new_cap * sizeof(T));
+ if (!new_data)
+ return false;
+ data_ = static_cast<T *>(new_data);
+ capacity_ = new_cap;
+ return true;
+ } else {
+ void *new_raw = ::malloc(new_cap * sizeof(T));
+ if (!new_raw)
+ return false;
+ T *new_data = static_cast<T *>(new_raw);
+ for (size_t i = 0; i < size_; ++i) {
+ new (new_data + i) T(cpp::move(data_[i]));
+ data_[i].~T();
+ }
+ ::free(data_);
+ data_ = new_data;
+ capacity_ = new_cap;
+ return true;
+ }
+ }
+
+public:
+ LIBC_INLINE constexpr vector() = default;
+
+ LIBC_INLINE ~vector() { deallocate(); }
+
+ // Move constructor
+ LIBC_INLINE vector(vector &&other) noexcept
+ : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
+ other.data_ = nullptr;
+ other.size_ = 0;
+ other.capacity_ = 0;
+ }
+
+ // Move assignment
+ LIBC_INLINE vector &operator=(vector &&other) noexcept {
+ if (this != &other) {
+ deallocate();
+ data_ = other.data_;
+ size_ = other.size_;
+ capacity_ = other.capacity_;
+ other.data_ = nullptr;
+ other.size_ = 0;
+ other.capacity_ = 0;
+ }
+ return *this;
+ }
+
+ // Copy operations are deleted to prevent accidental implicit allocations.
+ vector(const vector &) = delete;
+ vector &operator=(const vector &) = delete;
+
+ // Element access
+ [[nodiscard]] LIBC_INLINE reference operator[](size_t i) {
+ LIBC_ASSERT(i < size_);
+ return data_[i];
+ }
+
+ [[nodiscard]] LIBC_INLINE const_reference operator[](size_t i) const {
+ LIBC_ASSERT(i < size_);
+ return data_[i];
+ }
+
+ [[nodiscard]] LIBC_INLINE pointer data() { return data_; }
+ [[nodiscard]] LIBC_INLINE const_pointer data() const { return data_; }
+
+ [[nodiscard]] LIBC_INLINE reference front() {
+ LIBC_ASSERT(size_ > 0);
+ return data_[0];
+ }
+
+ [[nodiscard]] LIBC_INLINE const_reference front() const {
+ LIBC_ASSERT(size_ > 0);
+ return data_[0];
+ }
+
+ [[nodiscard]] LIBC_INLINE reference back() {
+ LIBC_ASSERT(size_ > 0);
+ return data_[size_ - 1];
+ }
+
+ [[nodiscard]] LIBC_INLINE const_reference back() const {
+ LIBC_ASSERT(size_ > 0);
+ return data_[size_ - 1];
+ }
+
+ // Iterators
+ [[nodiscard]] LIBC_INLINE iterator begin() { return data_; }
+ [[nodiscard]] LIBC_INLINE const_iterator begin() const { return data_; }
+ [[nodiscard]] LIBC_INLINE const_iterator cbegin() const { return data_; }
+ [[nodiscard]] LIBC_INLINE iterator end() { return data_ + size_; }
+ [[nodiscard]] LIBC_INLINE const_iterator end() const { return data_ + size_; }
+ [[nodiscard]] LIBC_INLINE const_iterator cend() const {
+ return data_ + size_;
+ }
+
+ // Capacity
+ [[nodiscard]] LIBC_INLINE bool empty() const { return size_ == 0; }
+ [[nodiscard]] LIBC_INLINE size_t size() const { return size_; }
+ [[nodiscard]] LIBC_INLINE size_t capacity() const { return capacity_; }
+
+ // Reserves at least new_cap elements. Returns true on success, false on OOM.
+ [[nodiscard]] LIBC_INLINE bool reserve(size_t new_cap) {
+ if (new_cap <= capacity_)
+ return true;
+ if (new_cap > max_size())
+ return false;
+ return reallocate(new_cap);
+ }
+
+ LIBC_INLINE void shrink_to_fit() {
+ if (size_ == capacity_)
+ return;
+ if (size_ == 0) {
+ reset();
+ return;
+ }
+ static_cast<void>(reallocate(size_));
+ }
+
+ // Modifiers
+ template <typename... Args>
+ [[nodiscard]] LIBC_INLINE bool emplace_back(Args &&...args) {
+ if (size_ < capacity_) {
+ new (data_ + size_) T(cpp::forward<Args>(args)...);
+ ++size_;
+ return true;
+ }
+
+ size_t new_cap = DEFAULT_INITIAL_CAPACITY;
+ if (capacity_ > 0) {
+ if (capacity_ > max_size() / 2)
+ return false;
+ new_cap = capacity_ * 2;
+ }
+
+ void *new_raw = ::malloc(new_cap * sizeof(T));
+ if (!new_raw)
+ return false;
+ T *new_data = static_cast<T *>(new_raw);
+
+ // Construct the new element before moving/freeing old storage so that
+ // arguments referencing the vector's own buffer remain valid.
+ new (new_data + size_) T(cpp::forward<Args>(args)...);
+
+ for (size_t i = 0; i < size_; ++i) {
+ new (new_data + i) T(cpp::move(data_[i]));
+ data_[i].~T();
+ }
+ ::free(data_);
+ data_ = new_data;
+ capacity_ = new_cap;
+ ++size_;
+ return true;
+ }
+
+ [[nodiscard]] LIBC_INLINE bool push_back(const T &val) {
+ return emplace_back(val);
+ }
+
+ [[nodiscard]] LIBC_INLINE bool push_back(T &&val) {
+ return emplace_back(cpp::move(val));
+ }
+
+ LIBC_INLINE void pop_back() {
+ LIBC_ASSERT(size_ > 0);
+ --size_;
+ if constexpr (!is_trivially_destructible_v<T>)
+ data_[size_].~T();
+ }
+
+ LIBC_INLINE void clear() {
+ destroy_elements(0, size_);
+ size_ = 0;
+ }
+
+ // Deallocates backing memory and resets size and capacity to 0.
+ LIBC_INLINE void reset() { deallocate(); }
+
+ [[nodiscard]] LIBC_INLINE bool resize(size_t new_size) {
+ if (new_size < size_) {
+ destroy_elements(new_size, size_);
+ size_ = new_size;
+ return true;
+ }
+ if (new_size > size_) {
+ if (!reserve(new_size))
+ return false;
+ for (size_t i = size_; i < new_size; ++i)
+ new (data_ + i) T();
+ size_ = new_size;
+ }
+ return true;
+ }
+
+ [[nodiscard]] LIBC_INLINE bool resize(size_t new_size, const T &value) {
+ if (new_size < size_) {
+ destroy_elements(new_size, size_);
+ size_ = new_size;
+ return true;
+ }
+ if (new_size > size_) {
+ // Copy value before reserve in case value references this vector's data.
+ T val_copy(value);
+ if (!reserve(new_size))
+ return false;
+ for (size_t i = size_; i < new_size; ++i)
+ new (data_ + i) T(val_copy);
+ size_ = new_size;
+ }
+ return true;
+ }
+
+ LIBC_INLINE void swap(vector &other) noexcept {
+ cpp::swap(data_, other.data_);
+ cpp::swap(size_, other.size_);
+ cpp::swap(capacity_, other.capacity_);
+ }
+};
+
+template <typename T>
+LIBC_INLINE void swap(vector<T> &lhs, vector<T> &rhs) noexcept {
+ lhs.swap(rhs);
+}
+
+} // namespace cpp
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_CPP_VECTOR_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/CMakeLists.txt
index a32244e4785..8856d5e525b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/CMakeLists.txt
@@ -10,7 +10,9 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.macros.attributes
+ libc.src.__support.macros.properties.cpu_features
libc.src.errno.errno
+ libc.src.string.memory_utils.inline_memcpy
)
add_header_library(
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FEnvImpl.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FEnvImpl.h
index 46572260cbc..4c897e72438 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FEnvImpl.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FEnvImpl.h
@@ -19,6 +19,7 @@
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/architectures.h"
#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
#ifdef LIBC_COMPILER_HAS_STDC_FENV_ACCESS
#define LIBC_FENV_ACCESS_ON _Pragma("STDC FENV_ACCESS ON")
@@ -210,6 +211,64 @@ set_errno_if_required([[maybe_unused]] int err) {
}
}
+template <typename T>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void raise_overflow_except_if_required() {
+ raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+}
+
+template <typename T>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void raise_underflow_except_if_required() {
+ raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
+}
+
+#if defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT)
+template <>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void
+raise_overflow_except_if_required<float>() {
+ if (cpp::is_constant_evaluated()) {
+ return;
+ } else {
+ volatile float x = 0x1.0p127f;
+ x = x * 2.0f;
+ }
+}
+
+template <>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void
+raise_underflow_except_if_required<float>() {
+ if (cpp::is_constant_evaluated()) {
+ return;
+ } else {
+ volatile float x = 0x1.0p-126f;
+ x = x * 0x1.0p-50f;
+ }
+}
+#endif // LIBC_TARGET_CPU_HAS_FPU_FLOAT
+
+#if defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE)
+template <>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void
+raise_overflow_except_if_required<double>() {
+ if (cpp::is_constant_evaluated()) {
+ return;
+ } else {
+ volatile double x = 0x1.0p1023;
+ x = x * 2.0;
+ }
+}
+
+template <>
+LIBC_INLINE LIBC_CONSTEXPR_DEFAULT void
+raise_underflow_except_if_required<double>() {
+ if (cpp::is_constant_evaluated()) {
+ return;
+ } else {
+ volatile double x = 0x1.0p-1022;
+ x = x * 0x1.0p-100;
+ }
+}
+#endif // LIBC_TARGET_CPU_HAS_FPU_DOUBLE
+
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/NearestIntegerOperations.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/NearestIntegerOperations.h
index 203e3c43ae9..156a6de2556 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/NearestIntegerOperations.h
@@ -109,48 +109,44 @@ LIBC_INLINE constexpr T round(T x) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
- // If x is infinity NaN or zero, return it.
- if (bits.is_inf_or_nan() || bits.is_zero())
- return x;
-
- int exponent = bits.get_exponent();
-
- // If the exponent is greater than the most negative mantissa
- // exponent, then x is already an integer.
- if (exponent >= static_cast<int>(FPBits<T>::FRACTION_LEN))
- return x;
+ // x86 binary80 has NaN encodings with a non-all-ones exponent, so the
+ // biased-exponent check below does not cover every NaN representation.
+ if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
+ if (LIBC_UNLIKELY(bits.is_nan()))
+ return x;
+ }
- if (exponent == -1) {
- // Absolute value of x is greater than equal to 0.5 but less than 1.
- return FPBits<T>::one(bits.sign()).get_val();
+ uint16_t biased_exponent = bits.get_biased_exponent();
+
+ if (biased_exponent <= FPBits<T>::EXP_BIAS - 2 ||
+ LIBC_UNLIKELY(biased_exponent >=
+ FPBits<T>::EXP_BIAS + FPBits<T>::FRACTION_LEN)) {
+ // Outside the middle range, the exponent's top bit selects x or signed
+ // zero without another branch.
+ StorageType keep_mask = static_cast<StorageType>(
+ StorageType(0) -
+ static_cast<StorageType>(biased_exponent / (FPBits<T>::EXP_BIAS + 1)));
+ bits.set_uintval(static_cast<StorageType>(
+ bits.uintval() & (keep_mask | FPBits<T>::SIGN_MASK)));
+ return bits.get_val();
}
- if (exponent <= -2) {
- // Absolute value of x is less than 0.5.
- return FPBits<T>::zero(bits.sign()).get_val();
+ if (biased_exponent == FPBits<T>::EXP_BIAS - 1) {
+ // Absolute value of x is greater than or equal to 0.5 but less than 1.
+ return FPBits<T>::one(bits.sign()).get_val();
}
- uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
- bool half_bit_set =
- bool(bits.get_mantissa() & (StorageType(1) << (trim_size - 1)));
+ // 1 <= abs(x) < 2^FRACTION_LEN. Add the rounding bit and clear all
+ // fractional bits below the resulting integral value.
+ int exponent = static_cast<int>(biased_exponent) - FPBits<T>::EXP_BIAS;
StorageType x_u = bits.uintval();
- StorageType trunc_u =
- static_cast<StorageType>((x_u >> trim_size) << trim_size);
-
- // If x is already an integer, return it.
- if (trunc_u == x_u)
- return x;
-
- bits.set_uintval(trunc_u);
- T trunc_value = bits.get_val();
-
- if (!half_bit_set) {
- // Franctional part is less than 0.5 so round value is the
- // same as the trunc value.
- return trunc_value;
- } else {
- return bits.is_neg() ? trunc_value - T(1.0) : trunc_value + T(1.0);
- }
+ StorageType round_bit = static_cast<StorageType>(
+ StorageType(1) << (FPBits<T>::FRACTION_LEN - exponent - 1));
+ StorageType mask = static_cast<StorageType>((round_bit << 1) - 1);
+ bits.set_uintval(static_cast<StorageType>((x_u + round_bit) & ~mask));
+ if constexpr (get_fp_type<T>() == FPType::X86_Binary80)
+ bits.set_implicit_bit(true);
+ return bits.get_val();
}
template <typename T>
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index a2066d1025f..af5fbe59253 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -23,19 +23,65 @@
#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/string/memory_utils/inline_memcpy.h"
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
struct FEnv {
struct FPState {
- uint64_t StatusWord;
- uint64_t ControlWord;
+ struct alignas(uint64_t) Word {
+ unsigned char Bytes[sizeof(uint64_t)];
+
+ LIBC_INLINE operator uint32_t() const {
+ uint64_t value;
+ inline_memcpy(&value, Bytes, sizeof(value));
+ return static_cast<uint32_t>(value);
+ }
+
+ LIBC_INLINE Word &operator=(uint32_t value) {
+ uint64_t storage = value;
+ inline_memcpy(Bytes, &storage, sizeof(storage));
+ return *this;
+ }
+ };
+
+ Word StatusWord;
+ Word ControlWord;
};
static_assert(
sizeof(fenv_t) == sizeof(FPState),
"Internal floating point state does not match the public fenv_t type.");
+ static_assert(
+ alignof(fenv_t) == alignof(FPState),
+ "Internal floating point state alignment does not match the public "
+ "fenv_t type.");
+
+#ifndef FE_FLUSHTOZERO
+#ifdef FE_DENORM
+ static constexpr uint32_t FE_FLUSHTOZERO = FE_DENORM;
+#else
+ static constexpr uint32_t FE_FLUSHTOZERO = 0;
+#endif
+#endif
+
+ // These FPCR masks match the controllable FPCR bit definitions exposed by
+ // Darwin's arm64 <fenv.h>.
+ static constexpr uint32_t FPCR_TRAP_INVALID = 0x100;
+ static constexpr uint32_t FPCR_TRAP_DIVBYZERO = 0x200;
+ static constexpr uint32_t FPCR_TRAP_OVERFLOW = 0x400;
+ static constexpr uint32_t FPCR_TRAP_UNDERFLOW = 0x800;
+ static constexpr uint32_t FPCR_TRAP_INEXACT = 0x1000;
+ static constexpr uint32_t FPCR_TRAP_DENORMAL = 0x8000;
+ static constexpr uint32_t FPCR_FLUSH_TO_ZERO = 0x1000000;
+
+ static constexpr uint32_t FPSR_INVALID = 0x1;
+ static constexpr uint32_t FPSR_DIVBYZERO = 0x2;
+ static constexpr uint32_t FPSR_OVERFLOW = 0x4;
+ static constexpr uint32_t FPSR_UNDERFLOW = 0x8;
+ static constexpr uint32_t FPSR_INEXACT = 0x10;
+ static constexpr uint32_t FPSR_DENORMAL = 0x80;
static constexpr uint32_t TONEAREST = 0x0;
static constexpr uint32_t UPWARD = 0x1;
@@ -59,29 +105,37 @@ struct FEnv {
static constexpr uint32_t ROUNDING_CONTROL_BIT_POSITION = 22;
// In addition to the 5 floating point exceptions, macOS on arm64 defines
- // another floating point exception: FE_FLUSHTOZERO, which is controlled by
- // __fpcr_flush_to_zero bit in the FPCR register. This control bit is
- // located in a different place from FE_FLUSHTOZERO status bit relative to
- // the other exceptions.
+ // another floating point exception: FE_FLUSHTOZERO, also called the input
+ // denormal exception. Its trap-enable bit is FPCR_TRAP_DENORMAL, while
+ // FPCR_FLUSH_TO_ZERO is a separate FPCR mode control.
+ LIBC_INLINE static uint32_t exception_value_from_macro(uint32_t excepts) {
+ return ((excepts & FE_INVALID) ? EX_INVALID : 0) |
+ ((excepts & FE_DIVBYZERO) ? EX_DIVBYZERO : 0) |
+ ((excepts & FE_OVERFLOW) ? EX_OVERFLOW : 0) |
+ ((excepts & FE_UNDERFLOW) ? EX_UNDERFLOW : 0) |
+ ((excepts & FE_INEXACT) ? EX_INEXACT : 0) |
+ ((excepts & FE_FLUSHTOZERO) ? EX_FLUSHTOZERO : 0);
+ }
+
LIBC_INLINE static uint32_t exception_value_from_status(uint32_t status) {
- return ((status & FE_INVALID) ? EX_INVALID : 0) |
- ((status & FE_DIVBYZERO) ? EX_DIVBYZERO : 0) |
- ((status & FE_OVERFLOW) ? EX_OVERFLOW : 0) |
- ((status & FE_UNDERFLOW) ? EX_UNDERFLOW : 0) |
- ((status & FE_INEXACT) ? EX_INEXACT : 0) |
- ((status & FE_FLUSHTOZERO) ? EX_FLUSHTOZERO : 0);
+ return ((status & FPSR_INVALID) ? EX_INVALID : 0) |
+ ((status & FPSR_DIVBYZERO) ? EX_DIVBYZERO : 0) |
+ ((status & FPSR_OVERFLOW) ? EX_OVERFLOW : 0) |
+ ((status & FPSR_UNDERFLOW) ? EX_UNDERFLOW : 0) |
+ ((status & FPSR_INEXACT) ? EX_INEXACT : 0) |
+ ((status & FPSR_DENORMAL) ? EX_FLUSHTOZERO : 0);
}
LIBC_INLINE static uint32_t exception_value_from_control(uint32_t control) {
- return ((control & __fpcr_trap_invalid) ? EX_INVALID : 0) |
- ((control & __fpcr_trap_divbyzero) ? EX_DIVBYZERO : 0) |
- ((control & __fpcr_trap_overflow) ? EX_OVERFLOW : 0) |
- ((control & __fpcr_trap_underflow) ? EX_UNDERFLOW : 0) |
- ((control & __fpcr_trap_inexact) ? EX_INEXACT : 0) |
- ((control & __fpcr_flush_to_zero) ? EX_FLUSHTOZERO : 0);
+ return ((control & FPCR_TRAP_INVALID) ? EX_INVALID : 0) |
+ ((control & FPCR_TRAP_DIVBYZERO) ? EX_DIVBYZERO : 0) |
+ ((control & FPCR_TRAP_OVERFLOW) ? EX_OVERFLOW : 0) |
+ ((control & FPCR_TRAP_UNDERFLOW) ? EX_UNDERFLOW : 0) |
+ ((control & FPCR_TRAP_INEXACT) ? EX_INEXACT : 0) |
+ ((control & FPCR_TRAP_DENORMAL) ? EX_FLUSHTOZERO : 0);
}
- LIBC_INLINE static uint32_t exception_value_to_status(uint32_t excepts) {
+ LIBC_INLINE static uint32_t exception_value_to_macro(uint32_t excepts) {
return ((excepts & EX_INVALID) ? FE_INVALID : 0) |
((excepts & EX_DIVBYZERO) ? FE_DIVBYZERO : 0) |
((excepts & EX_OVERFLOW) ? FE_OVERFLOW : 0) |
@@ -90,13 +144,22 @@ struct FEnv {
((excepts & EX_FLUSHTOZERO) ? FE_FLUSHTOZERO : 0);
}
+ LIBC_INLINE static uint32_t exception_value_to_status(uint32_t excepts) {
+ return ((excepts & EX_INVALID) ? FPSR_INVALID : 0) |
+ ((excepts & EX_DIVBYZERO) ? FPSR_DIVBYZERO : 0) |
+ ((excepts & EX_OVERFLOW) ? FPSR_OVERFLOW : 0) |
+ ((excepts & EX_UNDERFLOW) ? FPSR_UNDERFLOW : 0) |
+ ((excepts & EX_INEXACT) ? FPSR_INEXACT : 0) |
+ ((excepts & EX_FLUSHTOZERO) ? FPSR_DENORMAL : 0);
+ }
+
LIBC_INLINE static uint32_t exception_value_to_control(uint32_t excepts) {
- return ((excepts & EX_INVALID) ? __fpcr_trap_invalid : 0) |
- ((excepts & EX_DIVBYZERO) ? __fpcr_trap_divbyzero : 0) |
- ((excepts & EX_OVERFLOW) ? __fpcr_trap_overflow : 0) |
- ((excepts & EX_UNDERFLOW) ? __fpcr_trap_underflow : 0) |
- ((excepts & EX_INEXACT) ? __fpcr_trap_inexact : 0) |
- ((excepts & EX_FLUSHTOZERO) ? __fpcr_flush_to_zero : 0);
+ return ((excepts & EX_INVALID) ? FPCR_TRAP_INVALID : 0) |
+ ((excepts & EX_DIVBYZERO) ? FPCR_TRAP_DIVBYZERO : 0) |
+ ((excepts & EX_OVERFLOW) ? FPCR_TRAP_OVERFLOW : 0) |
+ ((excepts & EX_UNDERFLOW) ? FPCR_TRAP_UNDERFLOW : 0) |
+ ((excepts & EX_INEXACT) ? FPCR_TRAP_INEXACT : 0) |
+ ((excepts & EX_FLUSHTOZERO) ? FPCR_TRAP_DENORMAL : 0);
}
LIBC_INLINE static uint32_t get_control_word() { return __arm_rsr("fpcr"); }
@@ -114,36 +177,36 @@ struct FEnv {
LIBC_INLINE int enable_except(int excepts) {
uint32_t new_excepts =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
uint32_t control_word = FEnv::get_control_word();
uint32_t old_excepts = FEnv::exception_value_from_control(control_word);
if (new_excepts != old_excepts) {
control_word |= FEnv::exception_value_to_control(new_excepts);
FEnv::set_control_word(control_word);
}
- return static_cast<int>(FEnv::exception_value_to_status(old_excepts));
+ return static_cast<int>(FEnv::exception_value_to_macro(old_excepts));
}
LIBC_INLINE int disable_except(int excepts) {
uint32_t disabled_excepts =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
uint32_t control_word = FEnv::get_control_word();
uint32_t old_excepts = FEnv::exception_value_from_control(control_word);
control_word &= ~FEnv::exception_value_to_control(disabled_excepts);
FEnv::set_control_word(control_word);
- return static_cast<int>(FEnv::exception_value_to_status(old_excepts));
+ return static_cast<int>(FEnv::exception_value_to_macro(old_excepts));
}
LIBC_INLINE int get_except() {
uint32_t control_word = FEnv::get_control_word();
uint32_t enabled_excepts = FEnv::exception_value_from_control(control_word);
- return static_cast<int>(FEnv::exception_value_to_status(enabled_excepts));
+ return static_cast<int>(FEnv::exception_value_to_macro(enabled_excepts));
}
LIBC_INLINE int clear_except(int excepts) {
uint32_t status_word = FEnv::get_status_word();
uint32_t except_value =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
status_word &= ~FEnv::exception_value_to_status(except_value);
FEnv::set_status_word(status_word);
return 0;
@@ -152,15 +215,16 @@ LIBC_INLINE int clear_except(int excepts) {
LIBC_INLINE int test_except(int excepts) {
uint32_t statusWord = FEnv::get_status_word();
uint32_t ex_value =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
- return static_cast<int>(statusWord &
- FEnv::exception_value_to_status(ex_value));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
+ uint32_t raised_excepts = FEnv::exception_value_from_status(statusWord);
+ return static_cast<int>(
+ FEnv::exception_value_to_macro(raised_excepts & ex_value));
}
LIBC_INLINE int set_except(int excepts) {
uint32_t status_word = FEnv::get_status_word();
uint32_t new_exceptions =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
status_word |= FEnv::exception_value_to_status(new_exceptions);
FEnv::set_status_word(status_word);
return 0;
@@ -181,7 +245,7 @@ LIBC_INLINE int raise_except(int excepts) {
};
uint32_t to_raise =
- FEnv::exception_value_from_status(static_cast<uint32_t>(excepts));
+ FEnv::exception_value_from_macro(static_cast<uint32_t>(excepts));
int result = 0;
if (to_raise & FEnv::EX_INVALID) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/dyadic_float.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/dyadic_float.h
index e32906e3cf9..80335cc9f78 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/dyadic_float.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/dyadic_float.h
@@ -139,25 +139,21 @@ template <size_t Bits> struct DyadicFloat {
// Used for aligning exponents. Output might not be normalized.
LIBC_INLINE constexpr DyadicFloat &shift_left(unsigned shift_length) {
- if (shift_length < Bits) {
- exponent -= static_cast<int>(shift_length);
+ exponent -= static_cast<int>(shift_length);
+ if (shift_length < Bits)
mantissa <<= shift_length;
- } else {
- exponent = 0;
+ else
mantissa = MantissaType(0);
- }
return *this;
}
// Used for aligning exponents. Output might not be normalized.
LIBC_INLINE constexpr DyadicFloat &shift_right(unsigned shift_length) {
- if (shift_length < Bits) {
- exponent += static_cast<int>(shift_length);
+ exponent += static_cast<int>(shift_length);
+ if (shift_length < Bits)
mantissa >>= shift_length;
- } else {
- exponent = 0;
+ else
mantissa = MantissaType(0);
- }
return *this;
}
@@ -187,7 +183,7 @@ template <size_t Bits> struct DyadicFloat {
return DyadicFloat(result_sign, result_exponent, result_mantissa);
}
- template <typename T, bool ShouldSignalExceptions>
+ template <typename T, bool ShouldSignalExceptions = true>
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT cpp::enable_if_t<
cpp::is_floating_point_v<T> && (FPBits<T>::FRACTION_LEN < Bits), T>
generic_as() const {
@@ -204,7 +200,7 @@ template <size_t Bits> struct DyadicFloat {
if (unbiased_exp + FPBits::EXP_BIAS >= FPBits::MAX_BIASED_EXPONENT) {
if constexpr (ShouldSignalExceptions) {
set_errno_if_required(ERANGE);
- raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+ raise_overflow_except_if_required<T>();
}
#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
@@ -294,21 +290,21 @@ template <size_t Bits> struct DyadicFloat {
#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
if (ShouldSignalExceptions && (round || sticky)) {
- int excepts = FE_INEXACT;
if (FPBits(result).is_inf()) {
set_errno_if_required(ERANGE);
- excepts |= FE_OVERFLOW;
+ raise_overflow_except_if_required<T>();
} else if (underflow) {
set_errno_if_required(ERANGE);
- excepts |= FE_UNDERFLOW;
+ raise_underflow_except_if_required<T>();
+ } else {
+ raise_except_if_required(FE_INEXACT);
}
- raise_except_if_required(excepts);
}
return FPBits(result).get_val();
}
- template <typename T, bool ShouldSignalExceptions,
+ template <typename T, bool ShouldSignalExceptions = true,
typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
(FPBits<T>::FRACTION_LEN < Bits),
void>>
@@ -416,15 +412,14 @@ template <size_t Bits> struct DyadicFloat {
// Output is denormal after rounding, clear the implicit bit for
// 80-bit long double.
r_bits -= IMPLICIT_MASK;
+ }
- // TODO: IEEE Std 754-2019 lets implementers choose whether to check
- // for "tininess" before or after rounding for base-2 formats, as long
- // as the same choice is made for all operations. Our choice to check
- // after rounding might not be the same as the hardware's.
- if (ShouldSignalExceptions && round_and_sticky) {
- set_errno_if_required(ERANGE);
- raise_except_if_required(FE_UNDERFLOW);
- }
+ // Underflow exception and ERANGE are signaled when an unrounded result
+ // in the denormal range is inexact, even if destination rounding rounds
+ // it up to min_normal.
+ if (ShouldSignalExceptions && round_and_sticky) {
+ set_errno_if_required(ERANGE);
+ raise_underflow_except_if_required<T>();
}
return FPBits<T>(r_bits).get_val();
@@ -435,7 +430,7 @@ template <size_t Bits> struct DyadicFloat {
// Assume that it is already normalized.
// Output is rounded correctly with respect to the current rounding mode.
- template <typename T, bool ShouldSignalExceptions,
+ template <typename T, bool ShouldSignalExceptions = true,
typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
(FPBits<T>::FRACTION_LEN < Bits),
void>>
@@ -459,7 +454,7 @@ template <size_t Bits> struct DyadicFloat {
(FPBits<T>::FRACTION_LEN < Bits),
void>>
LIBC_INLINE explicit constexpr operator T() const {
- return as<T, /*ShouldSignalExceptions=*/false>();
+ return as<T, /*ShouldSignalExceptions=*/true>();
}
LIBC_INLINE constexpr MantissaType as_mantissa_type() const {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float80.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float80.h
index 25c7ba9251a..c0bc40cd6c1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float80.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float80.h
@@ -26,8 +26,11 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil {
struct Float80 {
+#if __SIZEOF_LONG_DOUBLE__ == 12
+ UInt<96> bits;
+#else
UInt128 bits;
-
+#endif
LIBC_INLINE Float80() = default;
LIBC_INLINE constexpr Float80(const Float80 &) = default;
LIBC_INLINE constexpr Float80(Float80 &&) = default;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/file.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/File/file.cpp
index fb8268a297a..d0366100525 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/file.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/file.cpp
@@ -510,51 +510,6 @@ int File::set_buffer(void *buffer, size_t size, int buffer_mode) {
return 0;
}
-File::ModeFlags File::mode_flags(const char *mode) {
- // First character in |mode| should be 'a', 'r' or 'w'.
- if (*mode != 'a' && *mode != 'r' && *mode != 'w')
- return 0;
-
- // There should be exaclty one main mode ('a', 'r' or 'w') character.
- // If there are more than one main mode characters listed, then
- // we will consider |mode| as incorrect and return 0;
- int main_mode_count = 0;
-
- ModeFlags flags = 0;
- for (; *mode != '\0'; ++mode) {
- switch (*mode) {
- case 'r':
- flags |= static_cast<ModeFlags>(OpenMode::READ);
- ++main_mode_count;
- break;
- case 'w':
- flags |= static_cast<ModeFlags>(OpenMode::WRITE);
- ++main_mode_count;
- break;
- case '+':
- flags |= static_cast<ModeFlags>(OpenMode::PLUS);
- break;
- case 'b':
- flags |= static_cast<ModeFlags>(ContentType::BINARY);
- break;
- case 'a':
- flags |= static_cast<ModeFlags>(OpenMode::APPEND);
- ++main_mode_count;
- break;
- case 'x':
- flags |= static_cast<ModeFlags>(CreateType::EXCLUSIVE);
- break;
- default:
- return 0;
- }
- }
-
- if (main_mode_count != 1)
- return 0;
-
- return flags;
-}
-
FileIOResult File::write_unlocked(const wchar_t *ws, size_t len) {
switch (orientation) {
case Orientation::BYTE:
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/file.h b/deps/v8/third_party/llvm-libc/src/src/__support/File/file.h
index 67879e6c993..072f5d38c7c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/file.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/file.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FILE_FILE_H
#define LLVM_LIBC_SRC___SUPPORT_FILE_FILE_H
+#include "file_mode.h"
#include "hdr/stdint_proxy.h"
#include "hdr/stdio_macros.h"
#include "hdr/types/off_t.h"
@@ -67,29 +68,17 @@ public:
using SeekFunc = ErrorOr<off_t>(File *, off_t, int);
using CloseFunc = int(File *);
- using ModeFlags = uint32_t;
-
- // The three different types of flags below are to be used with '|' operator.
- // Their values correspond to mutually exclusive bits in a 32-bit unsigned
- // integer value. A flag set can include both READ and WRITE if the file
- // is opened in update mode (ie. if the file was opened with a '+' the mode
- // string.)
- enum class OpenMode : ModeFlags {
- READ = 0x1,
- WRITE = 0x2,
- APPEND = 0x4,
- PLUS = 0x8,
- };
+ // This is a convenience RAII class to lock and unlock file objects.
+ class FileLock {
+ File *file;
- // Denotes a file opened in binary mode (which is specified by including
- // the 'b' character in teh mode string.)
- enum class ContentType : ModeFlags {
- BINARY = 0x10,
- };
+ public:
+ explicit FileLock(File *f) : file(f) { file->lock(); }
- // Denotes a file to be created for writing.
- enum class CreateType : ModeFlags {
- EXCLUSIVE = 0x100,
+ ~FileLock() { file->unlock(); }
+
+ FileLock(const FileLock &) = delete;
+ FileLock(FileLock &&) = delete;
};
private:
@@ -121,8 +110,8 @@ private:
// free-ed when close method is called on the stream.
bool own_buf;
- // The mode in which the file was opened.
- ModeFlags mode;
+ // Used to handle the File's mode
+ FileMode mode;
// Current read or write pointer.
size_t pos;
@@ -140,32 +129,12 @@ private:
Orientation orientation;
internal::mbstate mbstate;
- // This is a convenience RAII class to lock and unlock file objects.
- class FileLock {
- File *file;
-
- public:
- explicit FileLock(File *f) : file(f) { file->lock(); }
-
- ~FileLock() { file->unlock(); }
-
- FileLock(const FileLock &) = delete;
- FileLock(FileLock &&) = delete;
- };
-
protected:
- constexpr bool write_allowed() const {
- return mode & (static_cast<ModeFlags>(OpenMode::WRITE) |
- static_cast<ModeFlags>(OpenMode::APPEND) |
- static_cast<ModeFlags>(OpenMode::PLUS));
- }
+ constexpr bool write_allowed() const { return mode.write_allowed(); }
- constexpr bool read_allowed() const {
- return mode & (static_cast<ModeFlags>(OpenMode::READ) |
- static_cast<ModeFlags>(OpenMode::PLUS));
- }
+ constexpr bool read_allowed() const { return mode.read_allowed(); }
- void reset_stream_state_unlocked(ModeFlags new_mode) {
+ void reset_stream_state_unlocked(FileMode new_mode) {
mode = new_mode;
pos = 0;
prev_op = FileOp::NONE;
@@ -187,12 +156,12 @@ public:
// the set_buffer method and allocate a buffer.
constexpr File(WriteFunc *wf, ReadFunc *rf, SeekFunc *sf, CloseFunc *cf,
uint8_t *buffer, size_t buffer_size, int buffer_mode,
- bool owned, ModeFlags modeflags)
+ bool owned, FileMode mode)
: platform_write(wf), platform_read(rf), platform_seek(sf),
platform_close(cf), mutex(/*timed=*/false, /*recursive=*/false,
/*robust=*/false, /*pshared=*/false),
ungetc_buf{}, buf(buffer), bufsize(buffer_size), bufmode(buffer_mode),
- own_buf(owned), mode(modeflags), pos(0), prev_op(FileOp::NONE),
+ own_buf(owned), mode(mode), pos(0), prev_op(FileOp::NONE),
read_limit(0), eof(false), err(false),
orientation(Orientation::UNORIENTED), mbstate(), prev(nullptr),
next(nullptr) {
@@ -352,10 +321,6 @@ public:
return try_set_orientation_unlocked(o);
}
- // Returns an bit map of flags corresponding to enumerations of
- // OpenMode, ContentType and CreateType.
- static ModeFlags mode_flags(const char *mode);
-
private:
FileIOResult write_unlocked_impl(const void *data, size_t len);
FileIOResult read_unlocked_impl(void *data, size_t len);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/file_mode.h b/deps/v8/third_party/llvm-libc/src/src/__support/File/file_mode.h
new file mode 100644
index 00000000000..f9aece8d22a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/file_mode.h
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the implementation of FileMode class. This is the class
+/// that handles everything related to a file's mode.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FILE_FILE_MODE_H
+#define LLVM_LIBC_SRC___SUPPORT_FILE_FILE_MODE_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// FileMode class handles everything regarding the mode of the file, be it
+// opening mode or content type.
+class FileMode {
+public:
+ // FileMode constructor accepts the mode string as an argument.
+ // It performs validation against several rules and records the `file_mode`
+ // property to the specific mode.
+ constexpr FileMode(const char *mode) : file_mode_(0) {
+ // First character in |mode| should be 'a', 'r' or 'w'.
+ if (*mode != 'a' && *mode != 'r' && *mode != 'w')
+ return;
+
+ // There should be exactly one main mode ('a', 'r' or 'w') character.
+ // If there are more than one main mode characters listed, then
+ // we will consider |mode| as incorrect and set the file's mode to zero
+ // meaning the file's mode is in an invalid state.;
+ int main_mode_count = 0;
+
+ for (; *mode != '\0'; ++mode) {
+ switch (*mode) {
+ case 'r':
+ file_mode_ |= static_cast<Mode>(OpenMode::READ);
+ ++main_mode_count;
+ break;
+ case 'w':
+ file_mode_ |= static_cast<Mode>(OpenMode::WRITE);
+ ++main_mode_count;
+ break;
+ case '+':
+ file_mode_ |= static_cast<Mode>(OpenMode::PLUS);
+ break;
+ case 'b':
+ file_mode_ |= static_cast<Mode>(ContentType::BINARY);
+ break;
+ case 'a':
+ file_mode_ |= static_cast<Mode>(OpenMode::APPEND);
+ ++main_mode_count;
+ break;
+ case 'x':
+ file_mode_ |= static_cast<Mode>(CreateType::EXCLUSIVE);
+ break;
+ default:
+ file_mode_ = 0;
+ }
+ }
+
+ if (main_mode_count != 1)
+ file_mode_ = 0;
+ }
+
+ static const FileMode APPEND_MODE;
+ static const FileMode READ_MODE;
+ static const FileMode WRITE_MODE;
+
+ constexpr bool write_allowed() const {
+ return is_write() || is_append() || is_update();
+ }
+
+ constexpr bool read_allowed() const { return is_read() || is_update(); }
+
+ constexpr bool is_valid() const { return file_mode_ != 0; }
+
+ constexpr bool is_append() const {
+ return (file_mode_ & static_cast<Mode>(OpenMode::APPEND)) != 0;
+ }
+
+ constexpr bool is_update() const {
+ return (file_mode_ & static_cast<Mode>(OpenMode::PLUS)) != 0;
+ }
+
+ constexpr bool is_write() const {
+ return (file_mode_ & static_cast<Mode>(OpenMode::WRITE)) != 0;
+ }
+
+ constexpr bool is_read() const {
+ return (file_mode_ & static_cast<Mode>(OpenMode::READ)) != 0;
+ }
+
+ constexpr bool is_binary_format() const {
+ return (file_mode_ & static_cast<Mode>(ContentType::BINARY)) != 0;
+ }
+
+ // checks if a file was created for writing
+ constexpr bool is_exclusive_create() const {
+ return (file_mode_ & static_cast<Mode>(CreateType::EXCLUSIVE)) != 0;
+ }
+
+private:
+ // Mode is a generic or abstract mode bit for all kinds of modes
+ // (open-mode, 'content-mode', 'create-modes')
+ using Mode = uint32_t;
+
+ // Denotes the mode of the file.
+ //
+ // The three different types of flags below are to be used with '|' operator.
+ // Their values correspond to mutually exclusive bits in a 32-bit unsigned
+ // integer value. A flag set can include both READ and WRITE if the file
+ // is opened in update mode (ie. if the file was opened with a '+' the mode
+ // string.)
+ enum class OpenMode : Mode {
+ READ = 0x1,
+ WRITE = 0x2,
+ APPEND = 0x4,
+ PLUS = 0x8,
+ };
+
+ // Denotes a file opened in binary mode (which is specified by including
+ // the 'b' character in the mode string.)
+ enum class ContentType : Mode {
+ BINARY = 0x10,
+ };
+
+ // Denotes a file to be created for writing.
+ enum class CreateType : Mode {
+ EXCLUSIVE = 0x100,
+ };
+
+ // This property tracks the mode for the particular file instance (i.e
+ // currently opened file)
+ Mode file_mode_;
+};
+
+LIBC_INLINE_VAR constexpr FileMode FileMode::APPEND_MODE("a");
+LIBC_INLINE_VAR constexpr FileMode FileMode::READ_MODE("r");
+LIBC_INLINE_VAR constexpr FileMode FileMode::WRITE_MODE("w");
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FILE_FILE_MODE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/CMakeLists.txt
index 336854d4429..d0e1df25289 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/CMakeLists.txt
@@ -8,6 +8,7 @@ add_object_library(
DEPENDS
libc.hdr.fcntl_macros
libc.hdr.stdio_macros
+ libc.hdr.types.mode_t
libc.hdr.sys_stat_macros
libc.hdr.types.FILE
libc.hdr.types.off_t
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.cpp
index 67b69b9f026..cc6a1fcbd31 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.cpp
@@ -7,13 +7,13 @@
//===----------------------------------------------------------------------===//
#include "file.h"
-
-#include "hdr/fcntl_macros.h" // For mode_t and other flags to the open syscall
+#include "file_flags.h"
#include "hdr/stdio_macros.h"
#include "hdr/sys_stat_macros.h" // For S_IS*, S_IF*, and S_IR* flags.
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.h"
+#include "src/__support/File/file_mode.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/dup2.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/fcntl.h"
@@ -68,42 +68,38 @@ int linux_file_close(File *f) {
return retval;
}
-static int mode_flags_to_open_flags(File::ModeFlags modeflags) {
- using ModeFlags = File::ModeFlags;
+static int map_c_mode_flags_to_linux_open_flags(const FileMode &file_mode) {
int open_flags = 0;
- if (modeflags & ModeFlags(File::OpenMode::APPEND)) {
- open_flags = O_CREAT | O_APPEND;
- if (modeflags & ModeFlags(File::OpenMode::PLUS))
- open_flags |= O_RDWR;
- else
- open_flags |= O_WRONLY;
- } else if (modeflags & ModeFlags(File::OpenMode::WRITE)) {
- open_flags = O_CREAT | O_TRUNC;
- if (modeflags & ModeFlags(File::OpenMode::PLUS))
- open_flags |= O_RDWR;
- else
- open_flags |= O_WRONLY;
- } else {
- if (modeflags & ModeFlags(File::OpenMode::PLUS))
- open_flags |= O_RDWR;
- else
- open_flags |= O_RDONLY;
- }
+
+ // handle access patterns i.e whether the file should be in
+ // only read, write modes or both.
+ if (file_mode.is_update())
+ open_flags = LinuxFileFlags::READ_AND_WRITE;
+ else if (file_mode.is_append() || file_mode.is_write())
+ open_flags = LinuxFileFlags::WRITE_ONLY;
+ else
+ open_flags = LinuxFileFlags::READ_ONLY;
+
+ // handle the behaviour of the file when accessed i.e should the file
+ // be appended to or truncate when created.
+ if (file_mode.is_append())
+ open_flags |= LinuxFileFlags::CREATE_AND_APPEND;
+ else if (file_mode.is_write())
+ open_flags |= LinuxFileFlags::CREATE_OR_TRUNCATE;
+
return open_flags;
}
ErrorOr<File *> openfile(const char *path, const char *mode) {
- auto modeflags = File::mode_flags(mode);
- if (modeflags == 0) {
+ const FileMode file_mode(mode);
+
+ if (!file_mode.is_valid()) {
return Error(EINVAL);
}
- int open_flags = mode_flags_to_open_flags(modeflags);
+ int open_flags = map_c_mode_flags_to_linux_open_flags(file_mode);
- // File created will have 0666 permissions.
- constexpr mode_t OPEN_MODE =
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-
- ErrorOr<int> fd = linux_syscalls::open(path, open_flags, OPEN_MODE);
+ ErrorOr<int> fd =
+ linux_syscalls::open(path, open_flags, LinuxFileFlags::OPEN_MODE);
if (!fd)
return Error(fd.error());
@@ -116,7 +112,7 @@ ErrorOr<File *> openfile(const char *path, const char *mode) {
}
AllocChecker ac;
auto *file = new (ac) LinuxFile(fd.value(), buffer, File::DEFAULT_BUFFER_SIZE,
- _IOFBF, true, modeflags);
+ _IOFBF, true, file_mode);
if (!ac)
return Error(ENOMEM);
File::add_file(file);
@@ -124,9 +120,9 @@ ErrorOr<File *> openfile(const char *path, const char *mode) {
}
ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
- using ModeFlags = File::ModeFlags;
- ModeFlags modeflags = File::mode_flags(mode);
- if (modeflags == 0) {
+ const FileMode file_mode(mode);
+
+ if (!file_mode.is_valid()) {
return Error(EINVAL);
}
@@ -136,25 +132,16 @@ ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
}
int fd_flags = result.value();
- using OpenMode = File::OpenMode;
- using ModeFlags = File::ModeFlags;
-
- constexpr ModeFlags REQUIRES_WRITE =
- static_cast<ModeFlags>(OpenMode::WRITE) |
- static_cast<ModeFlags>(OpenMode::APPEND) |
- static_cast<ModeFlags>(OpenMode::PLUS);
-
- constexpr ModeFlags REQUIRES_READ = static_cast<ModeFlags>(OpenMode::READ) |
- static_cast<ModeFlags>(OpenMode::PLUS);
-
- if (((fd_flags & O_ACCMODE) == O_RDONLY && (modeflags & REQUIRES_WRITE)) ||
- ((fd_flags & O_ACCMODE) == O_WRONLY && (modeflags & REQUIRES_READ))) {
+ if ((LinuxFileFlags::is_file_descriptor_opened_in_read_only(fd_flags) &&
+ file_mode.write_allowed()) ||
+ (LinuxFileFlags::is_file_descriptor_opened_in_write_only(fd_flags) &&
+ file_mode.read_allowed())) {
return Error(EINVAL);
}
bool do_seek = false;
- if ((modeflags & static_cast<ModeFlags>(OpenMode::APPEND)) &&
- !(fd_flags & O_APPEND)) {
+ if (file_mode.is_append() &&
+ !LinuxFileFlags::file_has_append_flag(fd_flags)) {
do_seek = true;
if (!linux_syscalls::fcntl(fd, F_SETFL,
reinterpret_cast<void *>(fd_flags | O_APPEND))
@@ -173,7 +160,7 @@ ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
}
AllocChecker ac;
auto *file = new (ac)
- LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, modeflags);
+ LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, file_mode);
if (!ac) {
return Error(ENOMEM);
}
@@ -192,26 +179,24 @@ ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
flush_unlocked();
- auto modeflags = File::mode_flags(mode);
+ const FileMode file_mode(mode);
if (path != nullptr) {
int old_fd = get_fd();
- if (modeflags == 0) {
+ if (!file_mode.is_valid()) {
if (old_fd >= 0) {
linux_syscalls::close(old_fd);
set_fd(-1);
}
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
return EINVAL;
}
- int open_flags = mode_flags_to_open_flags(modeflags);
-
- constexpr mode_t OPEN_MODE =
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ int open_flags = map_c_mode_flags_to_linux_open_flags(file_mode);
- ErrorOr<int> new_fd = linux_syscalls::open(path, open_flags, OPEN_MODE);
+ ErrorOr<int> new_fd =
+ linux_syscalls::open(path, open_flags, LinuxFileFlags::OPEN_MODE);
// If the new file fails to open, POSIX says we still have to close the old
// file.
@@ -223,7 +208,7 @@ int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
set_fd(-1);
}
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
return new_fd.error();
}
@@ -233,23 +218,23 @@ int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
auto dup_result = linux_syscalls::dup2(new_fd.value(), old_fd);
if (!dup_result) {
linux_syscalls::close(new_fd.value());
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
return dup_result.error();
}
auto close_result = linux_syscalls::close(new_fd.value());
if (!close_result) {
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
return close_result.error();
}
} else {
set_fd(new_fd.value());
}
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
return 0;
}
- if (modeflags == 0)
+ if (!file_mode.is_valid())
return EINVAL;
if (fd < 0)
@@ -260,34 +245,24 @@ int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
return EBADF;
int fd_flags = result.value();
- using OpenMode = File::OpenMode;
- using ModeFlags = File::ModeFlags;
-
- constexpr ModeFlags REQUIRES_WRITE =
- static_cast<ModeFlags>(OpenMode::WRITE) |
- static_cast<ModeFlags>(OpenMode::APPEND) |
- static_cast<ModeFlags>(OpenMode::PLUS);
-
- constexpr ModeFlags REQUIRES_READ = static_cast<ModeFlags>(OpenMode::READ) |
- static_cast<ModeFlags>(OpenMode::PLUS);
-
- if (((fd_flags & O_ACCMODE) == O_RDONLY && (modeflags & REQUIRES_WRITE)) ||
- ((fd_flags & O_ACCMODE) == O_WRONLY && (modeflags & REQUIRES_READ))) {
+ if ((LinuxFileFlags::is_file_descriptor_opened_in_read_only(fd_flags) &&
+ file_mode.write_allowed()) ||
+ (LinuxFileFlags::is_file_descriptor_opened_in_write_only(fd_flags) &&
+ file_mode.read_allowed())) {
return EBADF;
}
bool do_seek = false;
- bool is_append = modeflags & static_cast<ModeFlags>(OpenMode::APPEND);
- bool has_append_flag = fd_flags & O_APPEND;
+ bool has_append_flag = LinuxFileFlags::file_has_append_flag(fd_flags);
- if (is_append && !has_append_flag) {
+ if (file_mode.is_append() && !has_append_flag) {
if (!linux_syscalls::fcntl(fd, F_SETFL,
reinterpret_cast<void *>(fd_flags | O_APPEND))
.has_value()) {
return EBADF;
}
do_seek = true;
- } else if (!is_append && has_append_flag) {
+ } else if (!file_mode.is_append() && has_append_flag) {
if (!linux_syscalls::fcntl(fd, F_SETFL,
reinterpret_cast<void *>(fd_flags & ~O_APPEND))
.has_value()) {
@@ -295,7 +270,7 @@ int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
}
}
- reset_stream_state_unlocked(modeflags);
+ reset_stream_state_unlocked(file_mode);
if (do_seek) {
auto seek_result = linux_file_seek(this, 0, SEEK_END);
@@ -311,11 +286,8 @@ int get_fileno(File *f) {
}
int reopenfile(File *f, const char *path, const char *mode) {
- f->lock();
- int ret = reopenfile_unlocked(f, path, mode);
- f->unlock();
-
- return ret;
+ File::FileLock lock(f);
+ return reopenfile_unlocked(f, path, mode);
}
int reopenfile_unlocked(File *f, const char *path, const char *mode) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.h b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.h
index 700db415156..539957b8b22 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file.h
@@ -8,6 +8,7 @@
#include "hdr/types/off_t.h"
#include "src/__support/File/file.h"
+#include "src/__support/File/file_mode.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
@@ -22,10 +23,9 @@ class LinuxFile : public File {
public:
constexpr LinuxFile(int file_descriptor, uint8_t *buffer, size_t buffer_size,
- int buffer_mode, bool owned, File::ModeFlags modeflags)
+ int buffer_mode, bool owned, FileMode mode)
: File(&linux_file_write, &linux_file_read, &linux_file_seek,
- &linux_file_close, buffer, buffer_size, buffer_mode, owned,
- modeflags),
+ &linux_file_close, buffer, buffer_size, buffer_mode, owned, mode),
fd(file_descriptor) {}
int get_fd() const { return fd; }
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file_flags.h b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file_flags.h
new file mode 100644
index 00000000000..deb357c261d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/linux/file_flags.h
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the defualt constants of Linux file open flags.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/fcntl_macros.h" // For mode_t and other flags to the open syscall
+#include "hdr/sys_stat_macros.h" // For S_IS*, S_IF*, and S_IR* flags.
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/fcntl.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+class LinuxFileFlags {
+public:
+ static constexpr int CREATE_AND_APPEND = O_CREAT | O_APPEND;
+ static constexpr int READ_AND_WRITE = O_RDWR;
+ static constexpr int WRITE_ONLY = O_WRONLY;
+ static constexpr int READ_ONLY = O_RDONLY;
+ static constexpr int CREATE_OR_TRUNCATE = O_CREAT | O_TRUNC;
+
+ // File created will have 0666 permissions.
+ LIBC_INLINE static constexpr mode_t OPEN_MODE =
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+
+ LIBC_INLINE static constexpr int
+ is_file_descriptor_opened_in_read_only(int flag) {
+ return (flag & O_ACCMODE) == O_RDONLY;
+ }
+
+ LIBC_INLINE static constexpr int
+ is_file_descriptor_opened_in_write_only(int flag) {
+ return (flag & O_ACCMODE) == O_WRONLY;
+ }
+
+ LIBC_INLINE static constexpr int file_has_append_flag(int flag) {
+ return flag & O_APPEND;
+ }
+};
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/GPU/allocator.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/GPU/allocator.cpp
index c88a70708b9..75b9ea73e60 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/GPU/allocator.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/GPU/allocator.cpp
@@ -94,24 +94,21 @@ static inline uint32_t xorshift32(uint32_t &state) {
}
// Rounds the input value to the closest permitted chunk size. Here we accept
-// the sum of the closest three powers of two. For a 2MiB slab size this is 48
+// the sum of the closest three powers of two. For a 2MiB slab size this is 46
// different chunk sizes. This gives us average internal fragmentation of 87.5%.
static inline constexpr uint32_t get_chunk_size(uint32_t x) {
uint32_t y = x < MIN_SIZE ? MIN_SIZE : x;
uint32_t pow2 = BITS_IN_WORD - cpp::countl_zero(y - 1);
- uint32_t s0 = 0b0100 << (pow2 - 3);
- uint32_t s1 = 0b0110 << (pow2 - 3);
- uint32_t s2 = 0b0111 << (pow2 - 3);
- uint32_t s3 = 0b1000 << (pow2 - 3);
+ uint32_t s0 = 0b0110 << (pow2 - 3);
+ uint32_t s1 = 0b0111 << (pow2 - 3);
+ uint32_t s2 = 0b1000 << (pow2 - 3);
- if (s0 > y)
+ if (s0 >= y)
return (s0 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
- if (s1 > y)
+ if (s1 >= y)
return (s1 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
- if (s2 > y)
- return (s2 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
- return (s3 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
+ return (s2 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
}
// Converts a chunk size into an index suitable for a statically sized array.
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/baremetal/io.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/baremetal/io.h
index 5e691f26060..3a61fa8f453 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/baremetal/io.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/baremetal/io.h
@@ -9,8 +9,9 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H
-#include "include/llvm-libc-types/size_t.h"
-#include "include/llvm-libc-types/ssize_t.h"
+#include "hdr/types/off_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/ssize_t.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/macros/config.h"
@@ -47,10 +48,22 @@ namespace LIBC_NAMESPACE_DECL {
struct __llvm_libc_stdio_cookie;
+// Return the number of bytes read, which can be less than `size` and is zero at
+// end-of-file. On failure, return a negative errno value.
extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
+
+// Return the number of bytes written, which can be less than `size`. On
+// failure, return a negative errno value.
extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
size_t size);
+// Return the resulting absolute file position on success. On failure, return a
+// negative errno value.
+extern "C" off_t __llvm_libc_stdio_seek(void *cookie, off_t offset, int whence);
+
+// Return 0 on success or EOF on failure, matching fclose.
+extern "C" int __llvm_libc_stdio_close(void *cookie);
+
void write_to_stderr(cpp::string_view msg);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/CMakeLists.txt
index c0420e554dc..40aa7daab07 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/CMakeLists.txt
@@ -3,6 +3,7 @@ if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
endif()
add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
+add_subdirectory(syscall_wrappers)
add_object_library(
darwin_util
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/CMakeLists.txt
new file mode 100644
index 00000000000..b9927b4d2a3
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_header_library(
+ sigprocmask
+ HDRS
+ sigprocmask.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.hdr.types.sigset_t
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/sigprocmask.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/sigprocmask.h
new file mode 100644
index 00000000000..5e99ebb4215
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/darwin/syscall_wrappers/sigprocmask.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sigprocmask.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_SYSCALL_WRAPPERS_SIGPROCMASK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_SYSCALL_WRAPPERS_SIGPROCMASK_H
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/darwin/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace darwin_syscalls {
+
+LIBC_INLINE ErrorOr<int> sigprocmask(int how, const sigset_t *set,
+ sigset_t *oldset) {
+ // TODO: Use a 32-bit sigset_t on Darwin and remove this conversion.
+ uint32_t kernel_set = set ? static_cast<uint32_t>(set->__signals[0]) : 0;
+ uint32_t kernel_oldset = 0;
+ int ret = syscall_impl<int>(SYS_sigprocmask, how, set ? &kernel_set : nullptr,
+ oldset ? &kernel_oldset : nullptr);
+ if (ret != 0)
+ return Error(ret);
+
+ if (oldset)
+ oldset->__signals[0] =
+ static_cast<unsigned long>(kernel_oldset & 0x7FFFFFFFU);
+ return ret;
+}
+
+} // namespace darwin_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_DARWIN_SYSCALL_WRAPPERS_SIGPROCMASK_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 30fbda86f6b..f5f28f51f49 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -26,6 +26,18 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ getpid
+ HDRS
+ getpid.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.hdr.types.pid_t
+ libc.include.sys_syscall
+)
+
add_header_library(
sched_getaffinity
HDRS
@@ -203,6 +215,42 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ flistxattr
+ HDRS
+ flistxattr.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ listxattr
+ HDRS
+ listxattr.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ llistxattr
+ HDRS
+ llistxattr.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
add_header_library(
read
HDRS
@@ -398,10 +446,12 @@ add_header_library(
DEPENDS
libc.src.__support.OSUtil.osutil
libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigprocmask
+ libc.src.__support.OSUtil.linux.syscall_wrappers.tgkill
libc.src.__support.common
libc.src.__support.error_or
libc.src.__support.macros.config
libc.hdr.signal_macros
+ libc.hdr.types.pid_t
libc.hdr.types.sigset_t
libc.include.sys_syscall
)
@@ -445,6 +495,22 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ posix_fadvise
+ HDRS
+ posix_fadvise.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.stdint_proxy
+ libc.include.sys_syscall
+ libc.src.__support.CPP.bit
+ libc.src.__support.CPP.limits
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
add_header_library(
ptrace
HDRS
@@ -573,6 +639,20 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ mknodat
+ HDRS
+ mknodat.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.hdr.types.dev_t
+ libc.hdr.types.mode_t
+ libc.include.sys_syscall
+)
+
add_header_library(
chmod
HDRS
@@ -605,12 +685,13 @@ add_header_library(
HDRS
fchmodat.h
DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.types.mode_t
+ libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.common
libc.src.__support.error_or
libc.src.__support.macros.config
- libc.hdr.types.mode_t
- libc.include.sys_syscall
)
add_header_library(
@@ -640,6 +721,96 @@ add_header_library(
libc.src.__support.OSUtil.osutil
)
+add_header_library(
+ getegid
+ HDRS
+ getegid.h
+ DEPENDS
+ libc.hdr.types.gid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ getpgid
+ HDRS
+ getpgid.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ setuid
+ HDRS
+ setuid.h
+ DEPENDS
+ libc.hdr.types.uid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ setreuid
+ HDRS
+ setreuid.h
+ DEPENDS
+ libc.hdr.types.uid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ setgid
+ HDRS
+ setgid.h
+ DEPENDS
+ libc.hdr.types.gid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ setregid
+ HDRS
+ setregid.h
+ DEPENDS
+ libc.hdr.types.gid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ setpgid
+ HDRS
+ setpgid.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
add_header_library(
link
HDRS
@@ -715,6 +886,18 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ chroot
+ HDRS
+ chroot.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
add_header_library(
fcntl
HDRS
@@ -733,6 +916,18 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ flock
+ HDRS
+ flock.h
+ DEPENDS
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
add_header_library(
fsync
HDRS
@@ -1094,3 +1289,70 @@ add_header_library(
libc.src.__support.macros.config
libc.include.sys_syscall
)
+
+add_header_library(
+ getpriority
+ HDRS
+ getpriority.h
+ DEPENDS
+ libc.hdr.types.id_t
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ setpriority
+ HDRS
+ setpriority.h
+ DEPENDS
+ libc.hdr.types.id_t
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ tgkill
+ HDRS
+ tgkill.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ umask
+ HDRS
+ umask.h
+ DEPENDS
+ libc.hdr.types.mode_t
+ libc.include.sys_syscall
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.osutil
+)
+
+add_header_library(
+ fallocate
+ HDRS
+ fallocate.h
+ DEPENDS
+ libc.src.__support.macros.config
+ libc.src.__support.common
+ libc.src.__support.OSUtil.osutil
+ libc.include.sys_syscall
+ libc.hdr.types.off_t
+ libc.hdr.errno_macros
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.bit
+ libc.src.__support.error_or
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/chroot.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/chroot.h
new file mode 100644
index 00000000000..eab600d1988
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/chroot.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for chroot.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHROOT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHROOT_H
+
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> chroot(const char *path) {
+ return syscall_checked<int>(SYS_chroot, path);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CHROOT_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
new file mode 100644
index 00000000000..2d80c7256de
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fallocate.h
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of the fallocate, which is the
+/// base syscall wrapper for all fallocate dependent calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FALLOCATE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FALLOCATE_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/types/off_t.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> fallocate(int fd, int mode, off_t offset, off_t size) {
+ if constexpr (sizeof(long) == sizeof(uint32_t) &&
+ sizeof(off_t) == sizeof(uint64_t)) {
+ uint64_t offset_bits = cpp::bit_cast<uint64_t>(offset);
+ long offset_low = static_cast<long>(offset_bits & UINT32_MAX);
+ long offset_high = static_cast<long>(offset_bits >> 32);
+ uint64_t len_bits = cpp::bit_cast<uint64_t>(size);
+ long len_low = static_cast<long>(len_bits & UINT32_MAX);
+ long len_high = static_cast<long>(len_bits >> 32);
+ return syscall_checked<int>(SYS_fallocate, fd, mode, offset_low,
+ offset_high, len_low, len_high);
+ } else {
+ return syscall_checked<int>(SYS_fallocate, fd, mode, offset, size);
+ }
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+#endif
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
index 7b8ee1a079b..d294b9c36bd 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fchmodat.h
@@ -14,8 +14,9 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMODAT_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FCHMODAT_H
+#include "hdr/errno_macros.h"
#include "hdr/types/mode_t.h"
-#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
@@ -26,10 +27,14 @@ namespace linux_syscalls {
LIBC_INLINE ErrorOr<int> fchmodat(int fd, const char *path, mode_t mode,
int flags) {
- int ret = syscall_impl<int>(SYS_fchmodat, fd, path, mode, flags);
- if (ret < 0)
- return Error(-ret);
- return ret;
+#if defined(SYS_fchmodat2)
+ auto ret = syscall_checked<int>(SYS_fchmodat2, fd, path, mode, flags);
+ if (ret || ret.error() != ENOSYS)
+ return ret;
+#endif
+ if (flags != 0)
+ return Error(ENOTSUP);
+ return syscall_checked<int>(SYS_fchmodat, fd, path, mode);
}
} // namespace linux_syscalls
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flistxattr.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flistxattr.h
new file mode 100644
index 00000000000..73cddc21b95
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flistxattr.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for flistxattr.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLISTXATTR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLISTXATTR_H
+
+#include "src/__support/OSUtil/linux/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<ssize_t> flistxattr(int fd, char *list, size_t size) {
+ return syscall_checked<ssize_t>(SYS_flistxattr, fd, list, size);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLISTXATTR_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flock.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flock.h
new file mode 100644
index 00000000000..42309bd8121
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/flock.h
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for flock.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLOCK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLOCK_H
+
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> flock(int fd, int op) {
+ return syscall_checked<int>(SYS_flock, fd, op);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FLOCK_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getegid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getegid.h
new file mode 100644
index 00000000000..4451ce0993b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getegid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getegid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETEGID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETEGID_H
+
+#include "hdr/types/gid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE gid_t getegid() {
+ // getegid is expected to always succeed, thus no error checking here.
+ return syscall_impl<gid_t>(SYS_getegid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETEGID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpgid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpgid.h
new file mode 100644
index 00000000000..4d04067531d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpgid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getpgid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPGID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPGID_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<pid_t> getpgid(pid_t pid) {
+ return syscall_checked<pid_t>(SYS_getpgid, pid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPGID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpid.h
new file mode 100644
index 00000000000..7644b67449f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpid.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getpid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPID_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE pid_t getpid() { return syscall_impl<pid_t>(SYS_getpid); }
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h
new file mode 100644
index 00000000000..41a173691a0
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getpriority
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H
+
+#include "hdr/types/id_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> getpriority(int which, id_t who) {
+ return syscall_checked<int>(SYS_getpriority, which, who);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/listxattr.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/listxattr.h
new file mode 100644
index 00000000000..77d002b496b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/listxattr.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for listxattr.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LISTXATTR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LISTXATTR_H
+
+#include "src/__support/OSUtil/linux/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<ssize_t> listxattr(const char *path, char *list,
+ size_t size) {
+ return syscall_checked<ssize_t>(SYS_listxattr, path, list, size);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LISTXATTR_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/llistxattr.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/llistxattr.h
new file mode 100644
index 00000000000..09fc80b3015
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/llistxattr.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for llistxattr.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LLISTXATTR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LLISTXATTR_H
+
+#include "src/__support/OSUtil/linux/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<ssize_t> llistxattr(const char *path, char *list,
+ size_t size) {
+ return syscall_checked<ssize_t>(SYS_llistxattr, path, list, size);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_LLISTXATTR_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/mknodat.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/mknodat.h
new file mode 100644
index 00000000000..50fd804ae61
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/mknodat.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for mknodat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKNODAT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKNODAT_H
+
+#include "hdr/types/dev_t.h"
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+// Note that the kernel expects |dev| in its own old-style encoding
+// ((major << 8) | minor, with the extended bits), which is not necessarily the
+// encoding of dev_t. Callers creating device nodes must encode it themselves;
+// callers creating FIFOs and sockets pass 0.
+LIBC_INLINE ErrorOr<int> mknodat(int dfd, const char *path, mode_t mode,
+ dev_t dev) {
+ return syscall_checked<int>(SYS_mknodat, dfd, path, mode, dev);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MKNODAT_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/posix_fadvise.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/posix_fadvise.h
new file mode 100644
index 00000000000..7049ab3e6fd
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/posix_fadvise.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// ErrorOr-returning syscall wrapper for posix_fadvise.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_POSIX_FADVISE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_POSIX_FADVISE_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> posix_fadvise(int fd, int64_t offset, int64_t len,
+ int advice) {
+ if constexpr (sizeof(long) == sizeof(uint32_t)) {
+ uint64_t offset_bits = cpp::bit_cast<uint64_t>(offset);
+ long offset_low = static_cast<long>(offset_bits & UINT32_MAX);
+ long offset_high = static_cast<long>(offset_bits >> 32);
+
+#if defined(SYS_arm_fadvise64_64) || defined(SYS_fadvise64_64)
+ uint64_t len_bits = cpp::bit_cast<uint64_t>(len);
+ long len_low = static_cast<long>(len_bits & UINT32_MAX);
+ long len_high = static_cast<long>(len_bits >> 32);
+#endif
+
+#if defined(SYS_arm_fadvise64_64)
+ return syscall_checked<int>(SYS_arm_fadvise64_64, fd, advice, offset_low,
+ offset_high, len_low, len_high);
+#elif defined(SYS_fadvise64_64)
+ return syscall_checked<int>(SYS_fadvise64_64, fd, offset_low, offset_high,
+ len_low, len_high, advice);
+#elif defined(SYS_fadvise64)
+ if (len < 0 ||
+ static_cast<uint64_t>(len) > cpp::numeric_limits<size_t>::max())
+ return Error(EINVAL);
+ return syscall_checked<int>(SYS_fadvise64, fd, offset_low, offset_high,
+ static_cast<size_t>(len), advice);
+#else
+#error "fadvise64 syscall not available."
+#endif
+ } else {
+#if defined(SYS_fadvise64)
+ return syscall_checked<int>(SYS_fadvise64, fd, offset, len, advice);
+#elif defined(SYS_fadvise64_64)
+ return syscall_checked<int>(SYS_fadvise64_64, fd, offset, len, advice);
+#else
+#error "fadvise64 syscall not available."
+#endif
+ }
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_POSIX_FADVISE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/raise.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/raise.h
index 2b61e4e624c..adbe2ab3a63 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/raise.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/raise.h
@@ -10,9 +10,11 @@
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RAISE_H
#include "hdr/signal_macros.h"
+#include "hdr/types/pid_t.h"
#include "hdr/types/sigset_t.h"
#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigprocmask.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/tgkill.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
@@ -54,9 +56,10 @@ LIBC_INLINE ErrorOr<int> raise(int sig) {
if (tid < 0)
return Error(-static_cast<int>(tid));
- int result = syscall_impl<int>(SYS_tgkill, pid, tid, sig);
- if (result < 0)
- return Error(-result);
+ auto result = linux_syscalls::tgkill(static_cast<pid_t>(pid),
+ static_cast<pid_t>(tid), sig);
+ if (!result.has_value())
+ return Error(result.error());
}
return status;
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setgid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setgid.h
new file mode 100644
index 00000000000..09a86b332a1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setgid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setgid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETGID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETGID_H
+
+#include "hdr/types/gid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setgid(gid_t gid) {
+ return syscall_checked<int>(SYS_setgid, gid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETGID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpgid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpgid.h
new file mode 100644
index 00000000000..7eb813a7824
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpgid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setpgid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETPGID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETPGID_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setpgid(pid_t pid, pid_t pgid) {
+ return syscall_checked<int>(SYS_setpgid, pid, pgid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETPGID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h
new file mode 100644
index 00000000000..0d3b7ede81f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setpriority
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H
+
+#include "hdr/types/id_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setpriority(int which, id_t who, int niceval) {
+ return syscall_checked<int>(SYS_setpriority, which, who, niceval);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setregid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setregid.h
new file mode 100644
index 00000000000..02ebc2187dc
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setregid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setregid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREGID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREGID_H
+
+#include "hdr/types/gid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setregid(gid_t rgid, gid_t egid) {
+ return syscall_checked<int>(SYS_setregid, rgid, egid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREGID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setreuid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setreuid.h
new file mode 100644
index 00000000000..68f08b24d3f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setreuid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setreuid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREUID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREUID_H
+
+#include "hdr/types/uid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setreuid(uid_t ruid, uid_t euid) {
+ return syscall_checked<int>(SYS_setreuid, ruid, euid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETREUID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setuid.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setuid.h
new file mode 100644
index 00000000000..8d99551b973
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/setuid.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for setuid.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETUID_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETUID_H
+
+#include "hdr/types/uid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> setuid(uid_t uid) {
+ return syscall_checked<int>(SYS_setuid, uid);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETUID_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/tgkill.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/tgkill.h
new file mode 100644
index 00000000000..094c724631e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/tgkill.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for tgkill.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TGKILL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TGKILL_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> tgkill(pid_t tgid, pid_t tid, int sig) {
+ return syscall_checked<int>(SYS_tgkill, tgid, tid, sig);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TGKILL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/umask.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/umask.h
new file mode 100644
index 00000000000..9544d5b340a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/umask.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for umask.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE mode_t umask(mode_t cmask) {
+ // umask is expected to always succeed, thus no error checking here.
+ return syscall_impl<mode_t>(SYS_umask, cmask);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/big_int.h b/deps/v8/third_party/llvm-libc/src/src/__support/big_int.h
index 5d2675909f2..3bc9833664c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/big_int.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/big_int.h
@@ -17,7 +17,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY, LIBC_LOOP_UNROLL
#include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128, LIBC_TYPES_HAS_INT64
#include "src/__support/math_extras.h" // add_with_carry, sub_with_borrow
@@ -204,6 +204,11 @@ LIBC_INLINE constexpr word scalar_multiply_with_carry(cpp::array<word, N> &dst,
return acc.carry();
}
+// Products of up to this many words are fully unrolled. 4 words is enough for
+// UInt128, the most used large integer type; larger integers may bloat the code
+// too much.
+LIBC_INLINE_VAR constexpr size_t MUL_UNROLL_MAX_WORDS = 4;
+
// Multiplication of 'lhs' by 'rhs' into 'dst'. Returns carry.
// This function is safe to use for signed numbers.
// https://stackoverflow.com/a/20793834
@@ -214,13 +219,21 @@ LIBC_INLINE constexpr word multiply_with_carry(cpp::array<word, O> &dst,
const cpp::array<word, N> &rhs) {
static_assert(O >= M + N);
Accumulator<word> acc;
- for (size_t i = 0; i < O; ++i) {
+ auto step = [&](size_t i) {
const size_t lower_idx = i < N ? 0 : i - N + 1;
const size_t upper_idx = i < M ? i : M - 1;
word carry = 0;
for (size_t j = lower_idx; j <= upper_idx; ++j)
carry += mul_add_with_carry(acc, lhs[j], rhs[i - j]);
dst[i] = acc.advance(carry);
+ };
+ if constexpr (O <= MUL_UNROLL_MAX_WORDS) {
+ LIBC_LOOP_UNROLL
+ for (size_t i = 0; i < O; ++i)
+ step(i);
+ } else {
+ for (size_t i = 0; i < O; ++i)
+ step(i);
}
return acc.carry();
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/fixed_point/fx_bits.h b/deps/v8/third_party/llvm-libc/src/src/__support/fixed_point/fx_bits.h
index 256bb3a967f..5c3b39d5a64 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/fixed_point/fx_bits.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/fixed_point/fx_bits.h
@@ -227,111 +227,143 @@ idiv(T x, T y) {
return static_cast<XType>(result);
}
-LIBC_INLINE long accum nrstep(long accum d, long accum x0) {
- auto v = x0 * (2.lk - (d * x0));
- return v;
-}
-
-// Divide the two integers and return a fixed_point value
-//
+// Divide two integers and return a fixed-point value.
// For reference, see:
// https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
-// https://stackoverflow.com/a/9231996
+// https://stackoverflow.com/a/9231996.
+template <typename FXType, typename IntType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<FXType>, FXType>
+fxdivi(IntType n, IntType d) {
+ using OutRep = FXRep<FXType>;
+ static_assert(cpp::is_signed_v<IntType> == (OutRep::SIGN_LEN > 0),
+ "IntType and FXType must have matching signedness");
+ constexpr bool IS_SIGNED = OutRep::SIGN_LEN > 0;
+ using UIntType = cpp::make_unsigned_t<IntType>;
-template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
// If the value of the second operand of the / operator is zero, the
- // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
+ // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16.
LIBC_CRASH_ON_VALUE(d, 0);
+ if (LIBC_UNLIKELY(n == 0))
+ return OutRep::ZERO();
+
+ // n == d and d != 0 means the quotient is 1. The general NR path can't
+ // guarantee landing on 1 exactly so special case for this.
+ if (LIBC_UNLIKELY(n == d)) {
+ if constexpr (OutRep::INTEGRAL_LEN > 0)
+ return static_cast<FXType>(1);
+ else
+ return OutRep::MAX();
+ }
- if (LIBC_UNLIKELY(n == 0)) {
- return FXRep<XType>::ZERO();
+ // Intermediate arithmetic is done in a wide fixed-point type.
+ using WideFXType =
+ cpp::conditional_t<IS_SIGNED, long accum, unsigned long accum>;
+ using WideRep = FXRep<WideFXType>;
+ using WideStorage = typename WideRep::StorageType;
+ constexpr int F = OutRep::FRACTION_LEN;
+ constexpr int WF = WideRep::FRACTION_LEN;
+
+ // Split each operand into a sign and a magnitude.
+ bool result_is_negative = false;
+ UIntType n_mag, d_mag;
+ if constexpr (IS_SIGNED) {
+ result_is_negative = (n < 0) != (d < 0);
+ n_mag = (n < 0) ? -static_cast<UIntType>(n) : static_cast<UIntType>(n);
+ d_mag = (d < 0) ? -static_cast<UIntType>(d) : static_cast<UIntType>(d);
+ } else {
+ n_mag = n;
+ d_mag = d;
}
- auto is_power_of_two = [](int n) { return (n > 0) && ((n & (n - 1)) == 0); };
- long accum max_val = static_cast<long accum>(FXRep<XType>::MAX());
- long accum min_val = static_cast<long accum>(FXRep<XType>::MIN());
-
- if (is_power_of_two(cpp::abs(d))) {
- int k = cpp::countr_zero<uint32_t>(static_cast<uint32_t>(cpp::abs(d)));
- constexpr int F = FXRep<XType>::FRACTION_LEN;
- int64_t scaled_n = static_cast<int64_t>(n) << F;
- int64_t res64 = scaled_n >> k;
- constexpr int TOTAL_BITS = sizeof(XType) * 8;
- const int64_t max_limit = (1LL << (TOTAL_BITS - 1)) - 1;
- const int64_t min_limit = -(1LL << (TOTAL_BITS - 1));
- if (res64 > max_limit) {
- return FXRep<XType>::MAX();
- } else if (res64 < min_limit) {
- return FXRep<XType>::MIN();
- }
- long accum res_accum =
- static_cast<long accum>(res64) / static_cast<long accum>(1 << F);
- res_accum = (d < 0) ? static_cast<long accum>(-1) * res_accum : res_accum;
- if (res_accum > max_val) {
- return FXRep<XType>::MAX();
- } else if (res_accum < min_val) {
- return FXRep<XType>::MIN();
- }
- return static_cast<XType>(res_accum);
+
+ if constexpr (OutRep::INTEGRAL_LEN > 0) {
+ constexpr UInt128 MAX_UNITS = static_cast<UInt128>(1)
+ << OutRep::INTEGRAL_LEN;
+
+ if (LIBC_UNLIKELY(static_cast<UInt128>(n_mag) >=
+ MAX_UNITS * static_cast<UInt128>(d_mag)))
+ return result_is_negative ? OutRep::MIN() : OutRep::MAX();
}
- bool result_is_negative = ((n < 0) != (d < 0));
- int64_t n64 = static_cast<int64_t>(n);
- int64_t d64 = static_cast<int64_t>(d);
+ WideFXType res;
- uint64_t nv = static_cast<uint64_t>(n64 < 0 ? -n64 : n64);
- uint64_t dv = static_cast<uint64_t>(d64 < 0 ? -d64 : d64);
+ constexpr int INTERMEDIATE_BITS = cpp::numeric_limits<UIntType>::digits + WF;
+ using WideIntType =
+ cpp::conditional_t<(INTERMEDIATE_BITS <= 64), uint64_t, UInt128>;
- if (d == INT_MIN) {
- nv <<= 1;
- dv >>= 1;
- }
+ if ((d_mag & (d_mag - 1)) == 0) {
+ // d is a power of 2. n/d is an exact right shift.
+ int log2_d = cpp::countr_zero(d_mag);
- uint32_t clz = cpp::countl_zero<uint32_t>(static_cast<uint32_t>(dv)) - 1;
- uint64_t scaled_val = dv << clz;
- // Scale denominator to be in the range of [0.5,1]
- FXBits<long accum> d_scaled{scaled_val};
- uint64_t scaled_val_n = nv << clz;
- // Scale the numerator as much as the denominator to maintain correctness of
- // the original equation
- FXBits<long accum> n_scaled{scaled_val_n};
- long accum n_scaled_val = n_scaled.get_val();
- long accum d_scaled_val = d_scaled.get_val();
- // x0 = (48/17) - (32/17) * d_n
- long accum a = 0x2.d89d89d8p0lk; // 48/17 = 2.8235294...
- long accum b = 0x1.e1e1e1e1p0lk; // 32/17 = 1.8823529...
- // Error of the initial approximation, as derived
- // from the wikipedia article is
- // E0 = 1/17 = 0.059 (5.9%)
- long accum initial_approx = a - (b * d_scaled_val);
- // Since, 0.5 <= d_scaled_val <= 1.0, 0.9412 <= initial_approx <= 1.88235
- LIBC_ASSERT((initial_approx >= 0x0.78793dd9p0lk) &&
- (initial_approx <= 0x1.f0f0d845p0lk));
- // Each newton-raphson iteration will square the error, due
- // to quadratic convergence. So,
- // E1 = (0.059)^2 = 0.0034
- long accum val = nrstep(d_scaled_val, initial_approx);
- if constexpr (FXRep<XType>::FRACTION_LEN > 8) {
- // E2 = 0.0000121
- val = nrstep(d_scaled_val, val);
- if constexpr (FXRep<XType>::FRACTION_LEN > 16) {
- // E3 = 1.468e−10
- val = nrstep(d_scaled_val, val);
- }
+ WideIntType scaled_n = (static_cast<WideIntType>(n_mag) << WF) >> log2_d;
+
+ constexpr int WIDE_STORAGE_BITS = cpp::numeric_limits<WideStorage>::digits;
+ if (LIBC_UNLIKELY((static_cast<UInt128>(scaled_n) >> WIDE_STORAGE_BITS) !=
+ 0))
+ return result_is_negative ? OutRep::MIN() : OutRep::MAX();
+
+ res = FXBits<WideFXType>(static_cast<WideStorage>(scaled_n)).get_val();
+ } else if constexpr (WF <= F) {
+ WideIntType wide_n = static_cast<WideIntType>(n_mag) << WF;
+ WideIntType quotient = wide_n / static_cast<WideIntType>(d_mag);
+ res = FXBits<WideFXType>(static_cast<WideStorage>(quotient)).get_val();
+ } else {
+ // General case: Approximate 1/d, then multiply by n.
+
+ // Normalize d_mag into a WF fraction value in [0.5, 1) and apply the same
+ // shift to n_mag so that n_scaled/d_scaled = n/d.
+ constexpr int W = cpp::numeric_limits<UIntType>::digits;
+ int d_msb = (W - 1) - cpp::countl_zero(d_mag);
+ int norm_shift = (WF - 1) - d_msb;
+
+ auto scale = [norm_shift](UIntType v) -> WideFXType {
+ WideStorage wide_v = static_cast<WideStorage>(v);
+ WideStorage shifted =
+ norm_shift >= 0 ? (wide_v << norm_shift) : (wide_v >> -norm_shift);
+ return FXBits<WideFXType>(shifted).get_val();
+ };
+
+ WideFXType d_scaled = scale(d_mag);
+ WideFXType n_scaled = scale(n_mag);
+
+ // Initial approximation of 1/d_scaled: x0 = 48/17 - (32/17) * d_scaled.
+ // d_scaled is in [0.5, 1) so x0 is in [0.941, 1.882] with a worst-case
+ // relative error bounded by 1/17 (~5.88%).
+ WideFXType a = static_cast<WideFXType>(0x2.d89d89d8p0lk); // 48/17
+ WideFXType b = static_cast<WideFXType>(0x1.e1e1e1e1p0lk); // 32/17
+ WideFXType initial_approx = a - b * d_scaled;
+
+ auto nrstep = [](WideFXType d_, WideFXType x0) {
+ return x0 * (static_cast<WideFXType>(2) - d_ * x0);
+ };
+
+ // Each iteration squares the relative error (quadratic convergence).
+ WideFXType recip = nrstep(d_scaled, initial_approx); // E1 <= 0.346%
+
+ if constexpr (F >= 7)
+ recip = nrstep(d_scaled, recip); // E2 <= 1.197e-5
+
+ if constexpr (F >= 15)
+ recip = nrstep(d_scaled, recip); // E3 <= 1.434e-10
+
+ res = n_scaled * recip;
}
- long accum res = n_scaled_val * val;
- if (result_is_negative) {
- res *= static_cast<long accum>(-1);
+ if constexpr (IS_SIGNED) {
+ if (result_is_negative)
+ res = -res;
}
- // Per clause 7.18a.6.1, saturate values on overflow
- if (res > max_val) {
- return FXRep<XType>::MAX();
- } else if (res < min_val) {
- return FXRep<XType>::MIN();
- } else {
- return static_cast<XType>(res);
+ // According to clause 7.18a.6.1, saturate the result on overflow.
+ WideFXType max_val = static_cast<WideFXType>(OutRep::MAX());
+ if (res > max_val)
+ return OutRep::MAX();
+ if constexpr (IS_SIGNED) {
+ WideFXType min_val = static_cast<WideFXType>(OutRep::MIN());
+ if (res < min_val)
+ return OutRep::MIN();
}
+
+ return static_cast<FXType>(res);
}
// Divide an integer operand by a fixed-point operand and return the
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/frac128.h b/deps/v8/third_party/llvm-libc/src/src/__support/frac128.h
index 298d1d9a61d..0a5a1edf614 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/frac128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/frac128.h
@@ -1,15 +1,21 @@
-//===-- 128-bit unsigned fractional type -------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of 128-bit unsigned fractional type.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_FRAC128_H
#define LLVM_LIBC_SRC___SUPPORT_FRAC128_H
#include "big_int.h"
+#include "frac64.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
@@ -17,6 +23,11 @@ namespace LIBC_NAMESPACE_DECL {
struct Frac128 : public UInt<128> {
using UInt<128>::UInt;
+ // Convert Frac128 number to Frac64 with truncation.
+ LIBC_INLINE constexpr Frac64 to_frac64() const { return Frac64(val[1]); }
+
+ LIBC_INLINE constexpr explicit operator Frac64() const { return to_frac64(); }
+
LIBC_INLINE constexpr Frac128 operator~() const {
Frac128 r{};
r.val[0] = ~val[0];
@@ -53,6 +64,14 @@ struct Frac128 : public UInt<128> {
*this = *this * other;
return *this;
}
+
+ LIBC_INLINE constexpr Frac128 operator<<(size_t s) const {
+ return Frac128((UInt<128>(*this) << s).val);
+ }
+
+ LIBC_INLINE constexpr Frac128 operator>>(size_t s) const {
+ return Frac128((UInt<128>(*this) >> s).val);
+ }
};
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/frac256.h b/deps/v8/third_party/llvm-libc/src/src/__support/frac256.h
new file mode 100644
index 00000000000..2f07a354060
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/frac256.h
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of 256-bit unsigned fractional type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FRAC256_H
+#define LLVM_LIBC_SRC___SUPPORT_FRAC256_H
+
+#include "big_int.h"
+#include "frac128.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+struct Frac256 : public UInt<256> {
+ using UInt<256>::UInt;
+
+ // Convert Frac256 number to Frac128 with truncation.
+ LIBC_INLINE constexpr Frac128 to_frac128() const {
+ return Frac128({val[2], val[3]});
+ }
+
+ LIBC_INLINE constexpr explicit operator Frac128() const {
+ return to_frac128();
+ }
+
+ // Convert Frac256 number to Frac64 with truncation.
+ LIBC_INLINE constexpr Frac64 to_frac64() const { return Frac64(val[3]); }
+
+ LIBC_INLINE constexpr explicit operator Frac64() const { return to_frac64(); }
+
+ LIBC_INLINE constexpr Frac256 operator~() const {
+ Frac256 r{};
+ r.val[0] = ~val[0];
+ r.val[1] = ~val[1];
+ r.val[2] = ~val[2];
+ r.val[3] = ~val[3];
+ return r;
+ }
+
+ LIBC_INLINE constexpr Frac256 operator+(const Frac256 &other) const {
+ UInt<256> r = UInt<256>(*this) + UInt<256>(other);
+ return Frac256(r.val);
+ }
+
+ LIBC_INLINE constexpr Frac256 operator-(const Frac256 &other) const {
+ UInt<256> r = UInt<256>(*this) - UInt<256>(other);
+ return Frac256(r.val);
+ }
+
+ LIBC_INLINE constexpr Frac256 operator*(const Frac256 &other) const {
+ UInt<256> r = UInt<256>::quick_mul_hi(UInt<256>(other));
+ return Frac256(r.val);
+ }
+
+ LIBC_INLINE constexpr Frac256 &operator+=(const Frac256 &other) {
+ *this = *this + other;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr Frac256 &operator-=(const Frac256 &other) {
+ *this = *this - other;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr Frac256 &operator*=(const Frac256 &other) {
+ *this = *this * other;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr Frac256 operator<<(size_t s) const {
+ return Frac256((UInt<256>(*this) << s).val);
+ }
+
+ LIBC_INLINE constexpr Frac256 operator>>(size_t s) const {
+ return Frac256((UInt<256>(*this) >> s).val);
+ }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FRAC256_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/frac64.h b/deps/v8/third_party/llvm-libc/src/src/__support/frac64.h
index bbb0d3bb309..350b0a8b701 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/frac64.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/frac64.h
@@ -51,6 +51,14 @@ struct Frac64 : public UInt<64> {
*this = *this * other;
return *this;
}
+
+ LIBC_INLINE constexpr Frac64 operator<<(size_t s) const {
+ return Frac64(val[0] << s);
+ }
+
+ LIBC_INLINE constexpr Frac64 operator>>(size_t s) const {
+ return Frac64(val[0] >> s);
+ }
};
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/attributes.h b/deps/v8/third_party/llvm-libc/src/src/__support/macros/attributes.h
index cffcabcd29b..1e8ebc13fea 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/macros/attributes.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/attributes.h
@@ -29,6 +29,14 @@
#define LIBC_INLINE_ASM __asm__ __volatile__
#define LIBC_UNUSED __attribute__((unused))
+#if __has_attribute(always_inline)
+#define LIBC_ALWAYS_INLINE LIBC_INLINE __attribute__((always_inline))
+#elif defined(LIBC_COMPILER_IS_MSVC) || defined(_MSC_VER)
+#define LIBC_ALWAYS_INLINE __forceinline
+#else
+#define LIBC_ALWAYS_INLINE LIBC_INLINE
+#endif // __has_attribute(always_inline)
+
#ifndef LIBC_HAS_BUILTIN_IS_CONSTANT_EVALUATED
#if (defined(LIBC_COMPILER_IS_GCC) && (LIBC_COMPILER_GCC_VER >= 900)) || \
(defined(LIBC_COMPILER_IS_CLANG) && LIBC_COMPILER_CLANG_VER >= 900)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/cpu_features.h b/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/cpu_features.h
index 08b5226feff..77daeb7c1fc 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/cpu_features.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/cpu_features.h
@@ -26,6 +26,16 @@
#define LIBC_TARGET_CPU_HAS_SVE2
#endif
+// __ARM_FEATURE_MVE is a bitfield
+#if defined(__ARM_FEATURE_MVE)
+#if (__ARM_FEATURE_MVE & 0x1)
+#define LIBC_TARGET_CPU_HAS_MVE
+#endif // LIBC_TARGET_CPU_HAS_MVE
+#if (__ARM_FEATURE_MVE & 0x2)
+#define LIBC_TARGET_CPU_HAS_MVE_FP
+#endif // LIBC_TARGET_CPU_HAS_MVE_FP
+#endif // __ARM_FEATURE_MVE
+
#if defined(__ARM_FEATURE_MOPS)
#define LIBC_TARGET_CPU_HAS_MOPS
#endif
@@ -34,6 +44,7 @@
#define LIBC_TARGET_CPU_HAS_SSE2
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 128
#endif
#if defined(__SSE4_2__)
@@ -42,6 +53,8 @@
#if defined(__AVX__)
#define LIBC_TARGET_CPU_HAS_AVX
+#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 256
#endif
#if defined(__AVX2__)
@@ -50,6 +63,8 @@
#if defined(__AVX512F__)
#define LIBC_TARGET_CPU_HAS_AVX512F
+#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
#endif
#if defined(__AVX512BW__)
@@ -77,6 +92,7 @@
#if defined(__ARM_NEON)
#define LIBC_TARGET_CPU_HAS_ARM_NEON
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
#endif
#if defined(__riscv_flen)
@@ -95,6 +111,10 @@
#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
#endif // __riscv_flen
+#if defined(__riscv_v_min_vlen)
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX __riscv_v_min_vlen
+#endif // __riscv_v_min_vlen
+
#if defined(__NVPTX__) || defined(__AMDGPU__) || defined(__SPIRV__)
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/math/CMakeLists.txt
index 272e9425a4e..8d6a1495e1c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/CMakeLists.txt
@@ -899,8 +899,8 @@ add_header_library(
HDRS
fmaximumf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -960,8 +960,8 @@ add_header_library(
HDRS
fmaximum_magf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -989,8 +989,8 @@ add_header_library(
HDRS
fmaximum_mag_numf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -1052,8 +1052,8 @@ add_header_library(
HDRS
fmaximum_numf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -1175,8 +1175,8 @@ add_header_library(
HDRS
fminimumf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -1236,8 +1236,8 @@ add_header_library(
HDRS
fminimum_magf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -1295,8 +1295,8 @@ add_header_library(
HDRS
fminimum_mag_numf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -1358,8 +1358,8 @@ add_header_library(
HDRS
fminimum_numf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -2453,6 +2453,8 @@ add_header_library(
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.attributes
libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.architectures
libc.src.__support.macros.properties.compiler
libc.src.__support.macros.properties.cpu_features
FLAGS
@@ -2543,9 +2545,10 @@ add_header_library(
roundf.h
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
- libc.src.__support.macros.config
libc.src.__support.macros.attributes
libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.architectures
libc.src.__support.macros.properties.compiler
libc.src.__support.macros.properties.cpu_features
FLAGS
@@ -2765,7 +2768,7 @@ add_header_library(
HDRS
copysignf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.manipulation_functions
libc.src.__support.macros.config
)
@@ -3069,20 +3072,64 @@ add_header_library(
)
add_header_library(
- expf
+ exp2f_float_utils
HDRS
- expf.h
+ exp2f_float_utils.h
+ DEPENDS
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ expf_double_eval
+ HDRS
+ expf_double_eval.h
DEPENDS
.exp_float_constants
- libc.src.__support.common
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.nearest_integer
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ expf_float_eval
+ HDRS
+ expf_float_eval.h
+ DEPENDS
+ .exp2f_float_utils
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
+add_header_library(
+ expf
+ HDRS
+ expf.h
+ DEPENDS
+ .expf_double_eval
+ .expf_float_eval
+ .expf_integer_eval
+ libc.hdr.fenv_macros
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
)
add_header_library(
@@ -3246,7 +3293,7 @@ add_header_library(
HDRS
fabsf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.config
)
@@ -3456,8 +3503,8 @@ add_header_library(
HDRS
fdimf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.float128
libc.src.__support.macros.config
)
@@ -4175,9 +4222,9 @@ add_header_library(
)
add_header_library(
- exp2f
+ exp2f_double_eval
HDRS
- exp2f.h
+ exp2f_double_eval.h
DEPENDS
.exp10f_utils
libc.src.__support.FPUtil.except_value_utils
@@ -4187,9 +4234,38 @@ add_header_library(
libc.src.__support.FPUtil.nearest_integer
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
+add_header_library(
+ exp2f_float_eval
+ HDRS
+ exp2f_float_eval.h
+ DEPENDS
+ .exp2f_float_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.common
+ libc.src.__support.macros.config
libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ exp2f
+ HDRS
+ exp2f.h
+ DEPENDS
+ .exp2f_double_eval
+ .exp2f_float_eval
libc.src.__support.common
- libc.src.errno.errno
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
)
add_header_library(
@@ -4278,16 +4354,47 @@ add_header_library(
)
add_header_library(
- exp10f
+ exp10f_double_eval
HDRS
- exp10f.h
+ exp10f_double_eval.h
DEPENDS
.exp10f_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ exp10f_float_eval
+ HDRS
+ exp10f_float_eval.h
+ DEPENDS
+ .exp2f_float_utils
+ libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
+add_header_library(
+ exp10f
+ HDRS
+ exp10f.h
+ DEPENDS
+ .exp10f_double_eval
+ .exp10f_float_eval
+ libc.src.__support.common
+ libc.src.__support.macros.config
libc.src.__support.macros.optimization
)
@@ -5266,20 +5373,32 @@ add_header_library(
pow
HDRS
pow.h
+ pow_fast.h
+ pow_utils.h
+ pow_accurate_128.h
+ pow_accurate_256.h
DEPENDS
.common_constants
.exp_constants
+ .exp2
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.CPP.bit
libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.nearest_integer
libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.rounding_mode
libc.src.__support.FPUtil.sqrt
+ libc.src.__support.frac64
+ libc.src.__support.frac128
+ libc.src.__support.frac256
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.uint128
)
add_header_library(
@@ -5291,6 +5410,7 @@ add_header_library(
.common_constants
.exp10f
.exp2f
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.bit
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/acosf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/acosf.h
index b901e684786..2f19ed4d99b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/acosf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/acosf.h
@@ -132,7 +132,7 @@ LIBC_INLINE float acosf(float x) {
//
// When -1 < x <= -0.5, we use the identity:
// acos(x) = pi - acos(-x)
- // which is reduced to the postive case.
+ // which is reduced to the positive case.
xbits.set_sign(Sign::POS);
double xd = static_cast<double>(xbits.get_val());
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/copysignf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/copysignf128.h
index 55b0c4caee2..5c77c95050e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/copysignf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/copysignf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COPYSIGNF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_COPYSIGNF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 copysignf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 copysignf128(Float128 x, Float128 y) {
return fputil::copysign(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COPYSIGNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/cos.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/cos.h
index 427132454a2..bd63d8d5d87 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/cos.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/cos.h
@@ -1,10 +1,15 @@
-//===-- Implementation header for cos ---------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for cos.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_COS_H
@@ -116,8 +121,9 @@ LIBC_INLINE double cos(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
return 1.0 + r_lo;
#else
- // Overall errors <= ulp(x^2/2) + 2^-69.
- double err = fputil::multiply_add(x_sq, 0x1.0p-53, 0x1.0p-69);
+ // Overall errors <= 1.0 * ulp(x^2) + 2^-69 for default rounding mode
+ // <= 2.0 * ulp(x^2) + 2^-69 for directed rounding mode.
+ double err = fputil::multiply_add(x_sq, 0x1.0p-51, 0x1.0p-69);
double r_lo_u = r_lo + err;
double r_lo_l = r_lo - err;
double r_upper = 1.0 + r_lo_u;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10.h
index 04588c2673c..01034874800 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10.h
@@ -211,16 +211,30 @@ LIBC_INLINE double exp10_denorm(double x) {
EXP10_ERR_D)
.value();
#else
+ using FPBits = fputil::FPBits<double>;
+
if (auto r = ziv_test_denorm(hi, exp_mid.hi, lo, EXP10_ERR_D);
- LIBC_LIKELY(r.has_value()))
- return r.value();
+ LIBC_LIKELY(r.has_value())) {
+ double res = r.value();
+ if (LIBC_UNLIKELY(FPBits(res).is_normal()))
+ return res;
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+ return res;
+ }
// Use double-double
DoubleDouble r_dd = exp10_double_double(x, kd, exp_mid);
if (auto r = ziv_test_denorm(hi, r_dd.hi, r_dd.lo, EXP10_ERR_DD);
- LIBC_LIKELY(r.has_value()))
- return r.value();
+ LIBC_LIKELY(r.has_value())) {
+ double res = r.value();
+ if (LIBC_UNLIKELY(FPBits(res).is_normal()))
+ return res;
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+ return res;
+ }
// Use 128-bit precision
DFloat128 r_f128 = exp10_f128(x, kd, idx1, idx2);
@@ -257,14 +271,14 @@ LIBC_INLINE double exp10_set_exceptional(double x) {
// exp(nan) = nan
if (xbits.is_nan())
- return x;
+ return x + FPBits::inf().get_val();
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
if (fputil::quick_get_round() == FE_UPWARD)
return FPBits::min_subnormal().get_val();
#endif
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW);
return 0.0;
}
@@ -274,14 +288,14 @@ LIBC_INLINE double exp10_set_exceptional(double x) {
// x >= log10(2^1024) or +inf/nan
// x is finite
if (x_u < 0x7ff0'0000'0000'0000ULL) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_overflow_except_if_required<double>();
#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
int rounding = fputil::quick_get_round();
if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
return FPBits::max_normal().get_val();
#endif
-
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
+ return FPBits::inf().get_val();
}
// x is +inf or nan
return x + FPBits::inf().get_val();
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f.h
index 642370a3d2a..67a9d24a5a2 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f.h
@@ -1,147 +1,44 @@
-//===-- Implementation header for exp10f ------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for exp10f.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_H
-#include "exp10f_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-
-namespace LIBC_NAMESPACE_DECL {
-namespace math {
-
-LIBC_INLINE float exp10f(float x) {
- using FPBits = typename fputil::FPBits<float>;
- FPBits xbits(x);
+#include "src/__support/macros/optimization.h"
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = x_u & 0x7fff'ffffU;
+#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
+ (defined(LIBC_MATH_HAS_SMALL_TABLES) || \
+ defined(LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT))
- // When |x| >= log10(2^128), or x is nan
- if (LIBC_UNLIKELY(x_abs >= 0x421a'209bU)) {
- // When x < log10(2^-150) or nan
- if (x_u > 0xc234'9e35U) {
- // exp(-Inf) = 0
- if (xbits.is_inf())
- return 0.0f;
- // exp(nan) = nan
- if (xbits.is_nan())
- return x;
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- if (fputil::fenv_is_round_up())
- return FPBits::min_subnormal().get_val();
-#endif
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW);
- return 0.0f;
- }
- // x >= log10(2^128) or nan
- if (xbits.is_pos() && (x_u >= 0x421a'209bU)) {
- // x is finite
- if (x_u < 0x7f80'0000U) {
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- int rounding = fputil::quick_get_round();
- if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
- return FPBits::max_normal().get_val();
-#endif
+#include "src/__support/math/exp10f_float_eval.h"
+#define LIBC_MATH_EXP10F_IMPL float_eval
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
- }
- // x is +inf or nan
- return x + FPBits::inf().get_val();
- }
- }
+#else // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#include "src/__support/math/exp10f_double_eval.h"
+#define LIBC_MATH_EXP10F_IMPL double_eval
- // When |x| <= log10(2)*2^-6
- if (LIBC_UNLIKELY(x_abs <= 0x3b9a'209bU)) {
- if (LIBC_UNLIKELY(x_u == 0xb25e'5bd9U)) { // x = -0x1.bcb7b2p-27f
-#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- return 0x1.fffffep-1f;
-#else
- if (fputil::fenv_is_round_to_nearest())
- return 0x1.fffffep-1f;
-#endif
- }
- // |x| < 2^-25
- // 10^x ~ 1 + log(10) * x
- if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
- return fputil::multiply_add(x, 0x1.26bb1cp+1f, 1.0f);
- }
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- return static_cast<float>(Exp10Base::powb_lo(x));
- }
-
- // Exceptional value.
- if (LIBC_UNLIKELY(x_u == 0x3d14'd956U)) { // x = 0x1.29b2acp-5f
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- if (fputil::fenv_is_round_up())
- return 0x1.1657c4p+0f;
-#endif
- }
-
- // Exact outputs when x = 1, 2, ..., 10.
- // Quick check mask: 0x800f'ffffU = ~(bits of 1.0f | ... | bits of 10.0f)
- if (LIBC_UNLIKELY((x_u & 0x800f'ffffU) == 0)) {
- switch (x_u) {
- case 0x3f800000U: // x = 1.0f
- return 10.0f;
- case 0x40000000U: // x = 2.0f
- return 100.0f;
- case 0x40400000U: // x = 3.0f
- return 1'000.0f;
- case 0x40800000U: // x = 4.0f
- return 10'000.0f;
- case 0x40a00000U: // x = 5.0f
- return 100'000.0f;
- case 0x40c00000U: // x = 6.0f
- return 1'000'000.0f;
- case 0x40e00000U: // x = 7.0f
- return 10'000'000.0f;
- case 0x41000000U: // x = 8.0f
- return 100'000'000.0f;
- case 0x41100000U: // x = 9.0f
- return 1'000'000'000.0f;
- case 0x41200000U: // x = 10.0f
- return 10'000'000'000.0f;
- }
- }
-
- // Range reduction: 10^x = 2^(mid + hi) * 10^lo
- // rr = (2^(mid + hi), lo)
- auto rr = exp_b_range_reduc<Exp10Base>(x);
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
- // The low part is approximated by a degree-5 minimax polynomial.
- // 10^lo ~ 1 + COEFFS[0] * lo + ... + COEFFS[4] * lo^5
- using fputil::multiply_add;
- double lo2 = rr.lo * rr.lo;
- // c0 = 1 + COEFFS[0] * lo
- double c0 = multiply_add(rr.lo, Exp10Base::COEFFS[0], 1.0);
- // c1 = COEFFS[1] + COEFFS[2] * lo
- double c1 = multiply_add(rr.lo, Exp10Base::COEFFS[2], Exp10Base::COEFFS[1]);
- // c2 = COEFFS[3] + COEFFS[4] * lo
- double c2 = multiply_add(rr.lo, Exp10Base::COEFFS[4], Exp10Base::COEFFS[3]);
- // p = c1 + c2 * lo^2
- // = COEFFS[1] + COEFFS[2] * lo + COEFFS[3] * lo^2 + COEFFS[4] * lo^3
- double p = multiply_add(lo2, c2, c1);
- // 10^lo ~ c0 + p * lo^2
- // 10^x = 2^(mid + hi) * 10^lo
- // ~ mh * (c0 + p * lo^2)
- // = (mh * c0) + p * (mh * lo^2)
- return static_cast<float>(multiply_add(p, lo2 * rr.mh, c0 * rr.mh));
-}
+using LIBC_MATH_EXP10F_IMPL::exp10f;
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
+#undef LIBC_MATH_EXP10F_IMPL
+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_double_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_double_eval.h
new file mode 100644
index 00000000000..e1a7cc9d68e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_double_eval.h
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Double-precision implementation of exp10f.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_DOUBLE_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_DOUBLE_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/exp10f_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace double_eval {
+
+LIBC_INLINE float exp10f(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= log10(2^128), or x is nan
+ if (LIBC_UNLIKELY(x_abs >= 0x421a'209bU)) {
+ // When x < log10(2^-150) or nan
+ if (x_u > 0xc234'9e35U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ return 0.0f;
+ }
+ // x >= log10(2^128) or nan
+ if (xbits.is_pos() && (x_u >= 0x421a'209bU)) {
+ // x is finite
+ if (x_u < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ }
+
+ // When |x| <= log10(2)*2^-6
+ if (LIBC_UNLIKELY(x_abs <= 0x3b9a'209bU)) {
+ if (LIBC_UNLIKELY(x_u == 0xb25e'5bd9U)) { // x = -0x1.bcb7b2p-27f
+#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return 0x1.fffffep-1f;
+#else // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_to_nearest())
+ return 0x1.fffffep-1f;
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ }
+ // |x| < 2^-25
+ // 10^x ~ 1 + log(10) * x
+ if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
+ return fputil::multiply_add(x, 0x1.26bb1cp+1f, 1.0f);
+ }
+
+ return static_cast<float>(Exp10Base::powb_lo(x));
+ }
+
+ // Exceptional value.
+ if (LIBC_UNLIKELY(x_u == 0x3d14'd956U)) { // x = 0x1.29b2acp-5f
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return 0x1.1657c4p+0f;
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ }
+
+ // Exact outputs when x = 1, 2, ..., 10.
+ // Quick check mask: 0x800f'ffffU = ~(bits of 1.0f | ... | bits of 10.0f)
+ if (LIBC_UNLIKELY((x_u & 0x800f'ffffU) == 0)) {
+ switch (x_u) {
+ case 0x3f800000U: // x = 1.0f
+ return 10.0f;
+ case 0x40000000U: // x = 2.0f
+ return 100.0f;
+ case 0x40400000U: // x = 3.0f
+ return 1'000.0f;
+ case 0x40800000U: // x = 4.0f
+ return 10'000.0f;
+ case 0x40a00000U: // x = 5.0f
+ return 100'000.0f;
+ case 0x40c00000U: // x = 6.0f
+ return 1'000'000.0f;
+ case 0x40e00000U: // x = 7.0f
+ return 10'000'000.0f;
+ case 0x41000000U: // x = 8.0f
+ return 100'000'000.0f;
+ case 0x41100000U: // x = 9.0f
+ return 1'000'000'000.0f;
+ case 0x41200000U: // x = 10.0f
+ return 10'000'000'000.0f;
+ }
+ }
+
+ // Range reduction: 10^x = 2^(mid + hi) * 10^lo
+ // rr = (2^(mid + hi), lo)
+ auto rr = exp_b_range_reduc<Exp10Base>(x);
+
+ // The low part is approximated by a degree-5 minimax polynomial.
+ // 10^lo ~ 1 + COEFFS[0] * lo + ... + COEFFS[4] * lo^5
+ using fputil::multiply_add;
+ double lo2 = rr.lo * rr.lo;
+ // c0 = 1 + COEFFS[0] * lo
+ double c0 = multiply_add(rr.lo, Exp10Base::COEFFS[0], 1.0);
+ // c1 = COEFFS[1] + COEFFS[2] * lo
+ double c1 = multiply_add(rr.lo, Exp10Base::COEFFS[2], Exp10Base::COEFFS[1]);
+ // c2 = COEFFS[3] + COEFFS[4] * lo
+ double c2 = multiply_add(rr.lo, Exp10Base::COEFFS[4], Exp10Base::COEFFS[3]);
+ // p = c1 + c2 * lo^2
+ // = COEFFS[1] + COEFFS[2] * lo + COEFFS[3] * lo^2 + COEFFS[4] * lo^3
+ double p = multiply_add(lo2, c2, c1);
+ // 10^lo ~ c0 + p * lo^2
+ // 10^x = 2^(mid + hi) * 10^lo
+ // ~ mh * (c0 + p * lo^2)
+ // = (mh * c0) + p * (mh * lo^2)
+ return static_cast<float>(multiply_add(p, lo2 * rr.mh, c0 * rr.mh));
+}
+
+} // namespace double_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_DOUBLE_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_float_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_float_eval.h
new file mode 100644
index 00000000000..304d3e31023
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp10f_float_eval.h
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Float-only implementation of exp10f.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_FLOAT_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_FLOAT_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/exp2f_float_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace float_eval {
+
+LIBC_INLINE float exp10f(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= log10(2^128), or x is nan
+ if (LIBC_UNLIKELY(x_abs >= 0x421a'209bU)) {
+ // When x < log10(2^-150) or nan
+ if (x_u > 0xc234'9e35U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ return 0.0f;
+ }
+ // x >= log10(2^128) or nan
+ if (xbits.is_pos() && (x_u >= 0x421a'209bU)) {
+ // x is finite
+ if (x_u < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ }
+
+ // |x| <= 2^-25
+ // 10^x ~ 1 + log(10) * x
+ if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
+ return fputil::multiply_add(x, 0x1.26bb1cp+1f, 1.0f);
+ }
+
+ // Exact outputs when x = 1, 2, ..., 10.
+ // Quick check mask: 0x800f'ffffU = ~(bits of 1.0f | ... | bits of 10.0f)
+ if (LIBC_UNLIKELY((x_u & 0x800f'ffffU) == 0)) {
+ switch (x_u) {
+ case 0x3f800000U: // x = 1.0f
+ return 10.0f;
+ case 0x40000000U: // x = 2.0f
+ return 100.0f;
+ case 0x40400000U: // x = 3.0f
+ return 1'000.0f;
+ case 0x40800000U: // x = 4.0f
+ return 10'000.0f;
+ case 0x40a00000U: // x = 5.0f
+ return 100'000.0f;
+ case 0x40c00000U: // x = 6.0f
+ return 1'000'000.0f;
+ case 0x40e00000U: // x = 7.0f
+ return 10'000'000.0f;
+ case 0x41000000U: // x = 8.0f
+ return 100'000'000.0f;
+ case 0x41100000U: // x = 9.0f
+ return 1'000'000'000.0f;
+ case 0x41200000U: // x = 10.0f
+ return 10'000'000'000.0f;
+ }
+ }
+
+ // Range reduction:
+ // k = round(x * log2(10))
+ // x * log2(10) = k + u, with |u| <= 0.5
+ // 10^x = 2^(k + u) = 2^k * 2^u
+#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
+ // Constants generated by Sollya with:
+ // > display = hexadecimal;
+ // > hi = round(log2(10), SG, RN);
+ // > lo = round(log2(10) - hi, SG, RN);
+ constexpr fputil::FloatFloat LOG2_10 = {0x1.2f346ep-24f, 0x1.a934fp+1f};
+
+ float kf = fputil::nearest_integer(x * LOG2_10.hi);
+ int k = static_cast<int>(kf);
+
+ float u_hi = fputil::multiply_add(x, LOG2_10.hi, -kf);
+ float u = fputil::multiply_add(x, LOG2_10.lo, u_hi);
+#else // !LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ // Cody-Waite reduction for non-FMA targets:
+ // Constants generated by Sollya with:
+ // > display = hexadecimal;
+ // > LOG2_10 = round(log2(10), SG, RN);
+ // > LOG10_2_HI = round(log10(2), 12, RN);
+ // > LOG10_2_LO = round(log10(2) - LOG10_2_HI, SG, RN);
+ constexpr float LOG2_10 = 0x1.a934fp+1f;
+ constexpr float LOG10_2_HI = 0x1.344p-2f;
+ constexpr float LOG10_2_LO = 0x1.3509f8p-18f;
+
+ float kf = fputil::nearest_integer(x * LOG2_10);
+ int k = static_cast<int>(kf);
+
+ float v_hi = fputil::multiply_add(-kf, LOG10_2_HI, x);
+ float v = fputil::multiply_add(-kf, LOG10_2_LO, v_hi);
+
+ // Convert reduced argument to base-2: u = v * log2(10)
+ float u = v * LOG2_10;
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+
+ return exp2f_eval(u, k);
+}
+
+} // namespace float_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP10F_FLOAT_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2.h
index 90790e435a7..084578796e4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2.h
@@ -190,16 +190,34 @@ LIBC_INLINE double exp2_denorm(double x) {
return ziv_test_denorm</*SKIP_ZIV_TEST=*/true>(hi, exp_mid.hi, lo, ERR_D)
.value();
#else
+ using FPBits = fputil::FPBits<double>;
+
if (auto r = ziv_test_denorm(hi, exp_mid.hi, lo, ERR_D);
- LIBC_LIKELY(r.has_value()))
- return r.value();
+ LIBC_LIKELY(r.has_value())) {
+ double res = r.value();
+ if (LIBC_UNLIKELY(FPBits(res).is_normal()))
+ return res;
+ if (x != fputil::nearest_integer(x)) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+ }
+ return res;
+ }
// Use double-double
DoubleDouble r_dd = exp2_double_double(dx, exp_mid);
if (auto r = ziv_test_denorm(hi, r_dd.hi, r_dd.lo, ERR_DD);
- LIBC_LIKELY(r.has_value()))
- return r.value();
+ LIBC_LIKELY(r.has_value())) {
+ double res = r.value();
+ if (LIBC_UNLIKELY(FPBits(res).is_normal()))
+ return res;
+ if (x != fputil::nearest_integer(x)) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+ }
+ return res;
+ }
// Use 128-bit precision
DFloat128 r_f128 = exp2_f128(dx, hi, idx1, idx2);
@@ -236,14 +254,14 @@ LIBC_INLINE double set_exceptional(double x) {
// exp(nan) = nan
if (xbits.is_nan())
- return x;
+ return x + FPBits::inf().get_val();
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
if (fputil::quick_get_round() == FE_UPWARD)
return FPBits::min_subnormal().get_val();
#endif
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW);
return 0.0;
}
@@ -253,14 +271,14 @@ LIBC_INLINE double set_exceptional(double x) {
// x >= 1024 or +inf/nan
// x is finite
if (x_u < 0x7ff0'0000'0000'0000ULL) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_overflow_except_if_required<double>();
#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
int rounding = fputil::quick_get_round();
if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
return FPBits::max_normal().get_val();
#endif
-
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
+ return FPBits::inf().get_val();
}
// x is +inf or nan
return x + FPBits::inf().get_val();
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f.h
index 1fa24c2013e..e7ce1ec29c0 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f.h
@@ -1,173 +1,44 @@
-//===-- Implementation header for exp2f -------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for exp2f.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_H
-#include "exp10f_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/macros/properties/cpu_features.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-namespace math {
-
-LIBC_INLINE float exp2f(float x) {
- using FPBits = typename fputil::FPBits<float>;
- FPBits xbits(x);
-
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = x_u & 0x7fff'ffffU;
-
- // When |x| >= 128, or x is nan, or |x| <= 2^-5
- if (LIBC_UNLIKELY(x_abs >= 0x4300'0000U || x_abs <= 0x3d00'0000U)) {
- // |x| <= 2^-5
- if (x_abs <= 0x3d00'0000) {
- // |x| < 2^-25
- if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
- return 1.0f + x;
- }
+#include "src/__support/macros/optimization.h"
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- constexpr uint32_t EXVAL1 = 0x3b42'9d37U;
- constexpr uint32_t EXVAL2 = 0xbcf3'a937U;
- constexpr uint32_t EXVAL_MASK = EXVAL1 & EXVAL2;
+#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
+ (defined(LIBC_MATH_HAS_SMALL_TABLES) || \
+ defined(LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT))
- // Check exceptional values.
- if (LIBC_UNLIKELY((x_u & EXVAL_MASK) == EXVAL_MASK)) {
- if (LIBC_UNLIKELY(x_u == EXVAL1)) { // x = 0x1.853a6ep-9f
- return fputil::round_result_slightly_down(0x1.00870ap+0f);
- } else if (LIBC_UNLIKELY(x_u == EXVAL2)) { // x = -0x1.e7526ep-6f
- return fputil::round_result_slightly_down(0x1.f58d62p-1f);
- }
- }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#include "src/__support/math/exp2f_float_eval.h"
+#define LIBC_MATH_EXP2F_IMPL float_eval
- // Minimax polynomial generated by Sollya with:
- // > P = fpminimax((2^x - 1)/x, 5, [|D...|], [-2^-5, 2^-5]);
- constexpr double COEFFS[] = {
- 0x1.62e42fefa39f3p-1, 0x1.ebfbdff82c57bp-3, 0x1.c6b08d6f2d7aap-5,
- 0x1.3b2ab6fc92f5dp-7, 0x1.5d897cfe27125p-10, 0x1.43090e61e6af1p-13};
- double xd = static_cast<double>(x);
- double xsq = xd * xd;
- double c0 = fputil::multiply_add(xd, COEFFS[1], COEFFS[0]);
- double c1 = fputil::multiply_add(xd, COEFFS[3], COEFFS[2]);
- double c2 = fputil::multiply_add(xd, COEFFS[5], COEFFS[4]);
- double p = fputil::polyeval(xsq, c0, c1, c2);
- double r = fputil::multiply_add(p, xd, 1.0);
- return static_cast<float>(r);
- }
+#else // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#include "src/__support/math/exp2f_double_eval.h"
+#define LIBC_MATH_EXP2F_IMPL double_eval
- // x >= 128
- if (xbits.is_pos()) {
- // x is finite
- if (x_u < 0x7f80'0000U) {
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- int rounding = fputil::quick_get_round();
- if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
- return FPBits::max_normal().get_val();
-#endif
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
- }
- // x is +inf or nan
- return x + FPBits::inf().get_val();
- }
- // x <= -150
- if (x_u >= 0xc316'0000U) {
- // exp(-Inf) = 0
- if (xbits.is_inf())
- return 0.0f;
- // exp(nan) = nan
- if (xbits.is_nan())
- return x;
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- if (fputil::fenv_is_round_up())
- return FPBits::min_subnormal().get_val();
-#endif
- if (x != 0.0f) {
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW);
- }
- return 0.0f;
- }
- }
-
- // For -150 < x < 128, to compute 2^x, we perform the following range
- // reduction: find hi, mid, lo such that:
- // x = hi + mid + lo, in which
- // hi is an integer,
- // 0 <= mid * 2^5 < 32 is an integer
- // -2^(-6) <= lo <= 2^-6.
- // In particular,
- // hi + mid = round(x * 2^5) * 2^(-5).
- // Then,
- // 2^x = 2^(hi + mid + lo) = 2^hi * 2^mid * 2^lo.
- // 2^mid is stored in the lookup table of 32 elements.
- // 2^lo is computed using a degree-5 minimax polynomial
- // generated by Sollya.
- // We perform 2^hi * 2^mid by simply add hi to the exponent field
- // of 2^mid.
-
- // kf = (hi + mid) * 2^5 = round(x * 2^5)
- float kf = 0;
- int k = 0;
-#ifdef LIBC_TARGET_CPU_HAS_NEAREST_INT
- kf = fputil::nearest_integer(x * 32.0f);
- k = static_cast<int>(kf);
-#else
- constexpr float HALF[2] = {0.5f, -0.5f};
- k = static_cast<int>(fputil::multiply_add(x, 32.0f, HALF[x < 0.0f]));
- kf = static_cast<float>(k);
-#endif // LIBC_TARGET_CPU_HAS_NEAREST_INT
-
- // dx = lo = x - (hi + mid) = x - kf * 2^(-5)
- double dx = fputil::multiply_add(-0x1.0p-5f, kf, x);
-
- // hi = floor(kf * 2^(-4))
- // exp_hi = shift hi to the exponent field of double precision.
- int64_t exp_hi =
- static_cast<int64_t>(static_cast<uint64_t>(k >> ExpBase::MID_BITS)
- << fputil::FPBits<double>::FRACTION_LEN);
- // mh = 2^hi * 2^mid
- // mh_bits = bit field of mh
- int64_t mh_bits = ExpBase::EXP_2_MID[k & ExpBase::MID_MASK] + exp_hi;
- double mh = fputil::FPBits<double>(uint64_t(mh_bits)).get_val();
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
- // Degree-5 polynomial approximating (2^x - 1)/x generating by Sollya with:
- // > P = fpminimax((2^x - 1)/x, 5, [|D...|], [-1/32. 1/32]);
- constexpr double COEFFS[5] = {0x1.62e42fefa39efp-1, 0x1.ebfbdff8131c4p-3,
- 0x1.c6b08d7061695p-5, 0x1.3b2b1bee74b2ap-7,
- 0x1.5d88091198529p-10};
- double dx_sq = dx * dx;
- double c1 = fputil::multiply_add(dx, COEFFS[0], 1.0);
- double c2 = fputil::multiply_add(dx, COEFFS[2], COEFFS[1]);
- double c3 = fputil::multiply_add(dx, COEFFS[4], COEFFS[3]);
- double p = fputil::multiply_add(dx_sq, c3, c2);
- // 2^x = 2^(hi + mid + lo)
- // = 2^(hi + mid) * 2^lo
- // ~ mh * (1 + lo * P(lo))
- // = mh + (mh*lo) * P(lo)
- return static_cast<float>(fputil::multiply_add(p, dx_sq * mh, c1 * mh));
-}
+using LIBC_MATH_EXP2F_IMPL::exp2f;
} // namespace math
-
} // namespace LIBC_NAMESPACE_DECL
+#undef LIBC_MATH_EXP2F_IMPL
+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_double_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_double_eval.h
new file mode 100644
index 00000000000..e0387f32e19
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_double_eval.h
@@ -0,0 +1,178 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Double-precision implementation of exp2f.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_DOUBLE_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_DOUBLE_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/exp10f_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace double_eval {
+
+LIBC_INLINE float exp2f(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= 128, or x is nan, or |x| <= 2^-5
+ if (LIBC_UNLIKELY(x_abs >= 0x4300'0000U || x_abs <= 0x3d00'0000U)) {
+ // |x| <= 2^-5
+ if (x_abs <= 0x3d00'0000) {
+ // |x| < 2^-25
+ if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
+ return 1.0f + x;
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ constexpr uint32_t EXVAL1 = 0x3b42'9d37U;
+ constexpr uint32_t EXVAL2 = 0xbcf3'a937U;
+ constexpr uint32_t EXVAL_MASK = EXVAL1 & EXVAL2;
+
+ // Check exceptional values.
+ if (LIBC_UNLIKELY((x_u & EXVAL_MASK) == EXVAL_MASK)) {
+ if (LIBC_UNLIKELY(x_u == EXVAL1)) { // x = 0x1.853a6ep-9f
+ return fputil::round_result_slightly_down(0x1.00870ap+0f);
+ } else if (LIBC_UNLIKELY(x_u == EXVAL2)) { // x = -0x1.e7526ep-6f
+ return fputil::round_result_slightly_down(0x1.f58d62p-1f);
+ }
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // Minimax polynomial generated by Sollya with:
+ // > P = fpminimax((2^x - 1)/x, 5, [|D...|], [-2^-5, 2^-5]);
+ constexpr double COEFFS[] = {
+ 0x1.62e42fefa39f3p-1, 0x1.ebfbdff82c57bp-3, 0x1.c6b08d6f2d7aap-5,
+ 0x1.3b2ab6fc92f5dp-7, 0x1.5d897cfe27125p-10, 0x1.43090e61e6af1p-13};
+ double xd = static_cast<double>(x);
+ double xsq = xd * xd;
+ double c0 = fputil::multiply_add(xd, COEFFS[1], COEFFS[0]);
+ double c1 = fputil::multiply_add(xd, COEFFS[3], COEFFS[2]);
+ double c2 = fputil::multiply_add(xd, COEFFS[5], COEFFS[4]);
+ double p = fputil::polyeval(xsq, c0, c1, c2);
+ double r = fputil::multiply_add(p, xd, 1.0);
+ return static_cast<float>(r);
+ }
+
+ // x >= 128
+ if (xbits.is_pos()) {
+ // x is finite
+ if (x_u < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ // x <= -150
+ if (x_u >= 0xc316'0000U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (x != 0.0f) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ }
+ return 0.0f;
+ }
+ }
+
+ // For -150 < x < 128, to compute 2^x, we perform the following range
+ // reduction: find hi, mid, lo such that:
+ // x = hi + mid + lo, in which
+ // hi is an integer,
+ // 0 <= mid * 2^5 < 32 is an integer
+ // -2^(-6) <= lo <= 2^-6.
+ // In particular,
+ // hi + mid = round(x * 2^5) * 2^(-5).
+ // Then,
+ // 2^x = 2^(hi + mid + lo) = 2^hi * 2^mid * 2^lo.
+ // 2^mid is stored in the lookup table of 32 elements.
+ // 2^lo is computed using a degree-5 minimax polynomial
+ // generated by Sollya.
+ // We perform 2^hi * 2^mid by simply add hi to the exponent field
+ // of 2^mid.
+
+ // kf = (hi + mid) * 2^5 = round(x * 2^5)
+ float kf = 0;
+ int k = 0;
+#ifdef LIBC_TARGET_CPU_HAS_NEAREST_INT
+ kf = fputil::nearest_integer(x * 32.0f);
+ k = static_cast<int>(kf);
+#else // !LIBC_TARGET_CPU_HAS_NEAREST_INT
+ constexpr float HALF[2] = {0.5f, -0.5f};
+ k = static_cast<int>(fputil::multiply_add(x, 32.0f, HALF[x < 0.0f]));
+ kf = static_cast<float>(k);
+#endif // LIBC_TARGET_CPU_HAS_NEAREST_INT
+
+ // dx = lo = x - (hi + mid) = x - kf * 2^(-5)
+ double dx = fputil::multiply_add(-0x1.0p-5f, kf, x);
+
+ // hi = floor(kf * 2^(-4))
+ // exp_hi = shift hi to the exponent field of double precision.
+ int64_t exp_hi =
+ static_cast<int64_t>(static_cast<uint64_t>(k >> ExpBase::MID_BITS)
+ << fputil::FPBits<double>::FRACTION_LEN);
+ // mh = 2^hi * 2^mid
+ // mh_bits = bit field of mh
+ int64_t mh_bits = ExpBase::EXP_2_MID[k & ExpBase::MID_MASK] + exp_hi;
+ double mh = fputil::FPBits<double>(uint64_t(mh_bits)).get_val();
+
+ // Degree-5 polynomial approximating (2^x - 1)/x generating by Sollya with:
+ // > P = fpminimax((2^x - 1)/x, 5, [|D...|], [-1/32. 1/32]);
+ constexpr double COEFFS[5] = {0x1.62e42fefa39efp-1, 0x1.ebfbdff8131c4p-3,
+ 0x1.c6b08d7061695p-5, 0x1.3b2b1bee74b2ap-7,
+ 0x1.5d88091198529p-10};
+ double dx_sq = dx * dx;
+ double c1 = fputil::multiply_add(dx, COEFFS[0], 1.0);
+ double c2 = fputil::multiply_add(dx, COEFFS[2], COEFFS[1]);
+ double c3 = fputil::multiply_add(dx, COEFFS[4], COEFFS[3]);
+ double p = fputil::multiply_add(dx_sq, c3, c2);
+ // 2^x = 2^(hi + mid + lo)
+ // = 2^(hi + mid) * 2^lo
+ // ~ mh * (1 + lo * P(lo))
+ // = mh + (mh*lo) * P(lo)
+ return static_cast<float>(fputil::multiply_add(p, dx_sq * mh, c1 * mh));
+}
+
+} // namespace double_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_DOUBLE_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_eval.h
new file mode 100644
index 00000000000..d1ea060478f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_eval.h
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Float-only implementation of exp2f.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/exp2f_float_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace float_eval {
+
+LIBC_INLINE float exp2f(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= 128, or x is nan, or |x| <= 2^-25
+ if (LIBC_UNLIKELY(x_abs >= 0x4300'0000U || x_abs <= 0x3280'0000U)) {
+ // |x| <= 2^-25
+ if (x_abs <= 0x3280'0000U) {
+ return 1.0f + x;
+ }
+
+ // x >= 128
+ if (xbits.is_pos()) {
+ // x is finite
+ if (x_u < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ // x <= -150
+ if (x_u >= 0xc316'0000U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (x != 0.0f) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ }
+ return 0.0f;
+ }
+ }
+
+ // Range reduction:
+ // k = round(x)
+ // x = k + u, with |u| <= 0.5
+ // 2^x = 2^k * 2^u
+ float kf = fputil::nearest_integer(x);
+ int k = static_cast<int>(kf);
+
+ float u = fputil::multiply_add(kf, -1.0f, x);
+ return exp2f_eval(u, k);
+}
+
+} // namespace float_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_utils.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_utils.h
new file mode 100644
index 00000000000..1c96050bea3
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/exp2f_float_utils.h
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Shared utilities and constants for single-precision exponential functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_UTILS_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace float_eval {
+
+// Compute y * 2^m for y in [0.5, 2.0) and m in [-150, 128].
+//
+// We divide into three cases depending on m:
+// 1. -126 <= m <= 127:
+// 2^m is a normal float (exponent field m + 127 in [1, 254]).
+// We can directly compute y * 2^m with a single multiplication.
+// The condition is checked using unsigned comparison: (m + 126) <= 253.
+//
+// 2. m > 127 (i.e., m = 128):
+// 2^m cannot be represented as a finite normal float (exponent field
+// 128 + 127 = 255 is inf). Instead, we compute:
+// y * 2^m = (2 * y) * 2^(m - 1).
+// Since y < 2.0, 2 * y is exact (simply increments the exponent of y),
+// and 2^(m - 1) = 2^127 is a normal float.
+//
+// 3. m < -126 (i.e., m in [-150, -127]):
+// The result is in the subnormal range (or underflows to 0).
+// To avoid double-rounding errors, we scale in two steps:
+// y * 2^m = (y * 2^(m + 25)) * 2^-25.
+// Since m >= -150, m + 25 >= -125, so 2^(m + 25) is a normal float.
+// The intermediate product (y * 2^(m + 25)) is normal and computed with
+// full precision. Then the final multiplication by 2^-25 rounds directly
+// to the target subnormal precision in a single rounding step.
+LIBC_INLINE float scale_exp2f(float y, int m) {
+ // -126 <= m <= 127: 2^m is a normal float.
+ if (LIBC_LIKELY(static_cast<uint32_t>(m + 126) <= 253)) {
+ uint32_t scale_bits = static_cast<uint32_t>(m + 127) << 23;
+ float scale = cpp::bit_cast<float>(scale_bits);
+ return y * scale;
+ }
+
+ // m = 128: 2^m cannot be represented as a normal float.
+ // Compute (2 * y) * 2^(m - 1), where 2 * y is exact and 2^(m - 1) is normal.
+ if (m > 127) {
+ uint32_t scale_bits = static_cast<uint32_t>(m - 1 + 127) << 23;
+ float scale = cpp::bit_cast<float>(scale_bits);
+ return (y * 2.0f) * scale;
+ }
+
+ // Subnormal result: m in [-150, -127].
+ // Compute (y * 2^(m + 25)) * 2^-25 so that the first product is normal and
+ // the second multiplication rounds directly to the subnormal result.
+ uint32_t scale_bits = static_cast<uint32_t>(m + 25 + 127) << 23;
+ float scale = cpp::bit_cast<float>(scale_bits);
+ return (y * scale) * 0x1.0p-25f;
+}
+
+// Degree-6 polynomial approximating 2^u - 1 = u * P(u) on [-0.5, 0.5] using
+// Estrin's scheme and exponent scaling.
+// Evaluates 2^x = 2^m * 2^u.
+// Generated by Sollya with:
+// > display = hexadecimal;
+// > P = fpminimax((2^x - 1)/x, 5, [|SG...|], [-0.5, 0.5]);
+// > dirtyinfnorm(1 + x * P - 2^x, [-0.5, 0.5]);
+// 0x1.68cb...p-28
+// > dirtyinfnorm((1 + x * P - 2^x) / 2^x, [-0.5, 0.5]);
+// 0x1.5109...p-28
+LIBC_INLINE float exp2f_eval(float u, int m) {
+ constexpr float COEFFS[6] = {0x1.62e430p-1f, 0x1.ebfbdep-3f,
+ 0x1.c6af9ep-5f, 0x1.3b2c58p-7f,
+ 0x1.5ef4a2p-10f, 0x1.427918p-13f};
+
+ float u2 = u * u;
+ float u4 = u2 * u2;
+
+ float p0 = fputil::multiply_add(u, COEFFS[1], COEFFS[0]);
+ float p1 = fputil::multiply_add(u, COEFFS[3], COEFFS[2]);
+ float p2 = fputil::multiply_add(u, COEFFS[5], COEFFS[4]);
+
+ float q0 = fputil::multiply_add(u2, p1, p0);
+ float p = fputil::multiply_add(u4, p2, q0);
+
+ float y = fputil::multiply_add(u, p, 1.0f);
+
+ return scale_exp2f(y, m);
+}
+
+} // namespace float_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_FLOAT_UTILS_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf.h
index f2c2c5319d2..a64b323e08b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf.h
@@ -1,120 +1,52 @@
-//===-- Implementation header for expf --------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for expf.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_H
-#include "exp_float_constants.h" // Lookup tables EXP_M1 and EXP_M2.
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
-namespace LIBC_NAMESPACE_DECL {
-
-namespace math {
+#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
+ (defined(LIBC_MATH_HAS_SMALL_TABLES) || \
+ defined(LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT))
-LIBC_INLINE float expf(float x) {
- using FPBits = typename fputil::FPBits<float>;
- FPBits xbits(x);
+#include "src/__support/math/expf_float_eval.h"
+#define LIBC_MATH_EXPF_IMPL float_eval
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = x_u & 0x7fff'ffffU;
+#elif !defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) && \
+ defined(LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY) && \
+ defined(LIBC_MATH_HAS_NO_EXCEPT) && defined(LIBC_MATH_HAS_NO_ERRNO)
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Exceptional values
- if (LIBC_UNLIKELY(x_u == 0xc236'bd8cU)) { // x = -0x1.6d7b18p+5f
- return 0x1.108a58p-66f - x * 0x1.0p-95f;
- }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#include "src/__support/math/expf_integer_eval.h"
+#define LIBC_MATH_EXPF_IMPL integer_eval
- // When |x| >= 89, |x| < 2^-25, or x is nan
- if (LIBC_UNLIKELY(x_abs >= 0x42b2'0000U || x_abs <= 0x3280'0000U)) {
- // |x| < 2^-25
- if (xbits.get_biased_exponent() <= 101) {
- return 1.0f + x;
- }
+#else
+#include "src/__support/math/expf_double_eval.h"
+#define LIBC_MATH_EXPF_IMPL double_eval
- // When x < log(2^-150) or nan
- if (xbits.uintval() >= 0xc2cf'f1b5U) {
- // exp(-Inf) = 0
- if (xbits.is_inf())
- return 0.0f;
- // exp(nan) = nan
- if (xbits.is_nan())
- return x;
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- if (fputil::fenv_is_round_up())
- return FPBits::min_subnormal().get_val();
-#endif
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_UNDERFLOW);
- return 0.0f;
- }
- // x >= 89 or nan
- if (xbits.is_pos() && (xbits.uintval() >= 0x42b2'0000)) {
- // x is finite
- if (xbits.uintval() < 0x7f80'0000U) {
-#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
- int rounding = fputil::quick_get_round();
- if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
- return FPBits::max_normal().get_val();
-#endif
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
- }
- // x is +inf or nan
- return x + FPBits::inf().get_val();
- }
- }
- // For -104 < x < 89, to compute exp(x), we perform the following range
- // reduction: find hi, mid, lo such that:
- // x = hi + mid + lo, in which
- // hi is an integer,
- // mid * 2^7 is an integer
- // -2^(-8) <= lo < 2^-8.
- // In particular,
- // hi + mid = round(x * 2^7) * 2^(-7).
- // Then,
- // exp(x) = exp(hi + mid + lo) = exp(hi) * exp(mid) * exp(lo).
- // We store exp(hi) and exp(mid) in the lookup tables EXP_M1 and EXP_M2
- // respectively. exp(lo) is computed using a degree-4 minimax polynomial
- // generated by Sollya.
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
- // x_hi = (hi + mid) * 2^7 = round(x * 2^7).
- float kf = fputil::nearest_integer(x * 0x1.0p7f);
- // Subtract (hi + mid) from x to get lo.
- double xd = static_cast<double>(fputil::multiply_add(kf, -0x1.0p-7f, x));
- int x_hi = static_cast<int>(kf);
- x_hi += 104 << 7;
- // hi = x_hi >> 7
- double exp_hi = EXP_M1[x_hi >> 7];
- // mid * 2^7 = x_hi & 0x0000'007fU;
- double exp_mid = EXP_M2[x_hi & 0x7f];
- // Degree-4 minimax polynomial generated by Sollya with the following
- // commands:
- // > display = hexadecimal;
- // > Q = fpminimax(expm1(x)/x, 3, [|D...|], [-2^-8, 2^-8]);
- // > Q;
- double exp_lo =
- fputil::polyeval(xd, 0x1p0, 0x1.ffffffffff777p-1, 0x1.000000000071cp-1,
- 0x1.555566668e5e7p-3, 0x1.55555555ef243p-5);
- return static_cast<float>(exp_hi * exp_mid * exp_lo);
-}
+using LIBC_MATH_EXPF_IMPL::expf;
} // namespace math
-
} // namespace LIBC_NAMESPACE_DECL
+#undef LIBC_MATH_EXPF_IMPL
+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_double_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_double_eval.h
new file mode 100644
index 00000000000..12f745a4bc6
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_double_eval.h
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Double-precision implementation of expf.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_DOUBLE_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_DOUBLE_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/exp_float_constants.h" // Lookup tables EXP_M1 and EXP_M2.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace double_eval {
+
+LIBC_INLINE float expf(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Exceptional values
+ if (LIBC_UNLIKELY(x_u == 0xc236'bd8cU)) { // x = -0x1.6d7b18p+5f
+ return 0x1.108a58p-66f - x * 0x1.0p-95f;
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // When |x| >= 89, |x| < 2^-25, or x is nan
+ if (LIBC_UNLIKELY(x_abs >= 0x42b2'0000U || x_abs <= 0x3280'0000U)) {
+ // |x| < 2^-25
+ if (xbits.get_biased_exponent() <= 101) {
+ return 1.0f + x;
+ }
+
+ // When x < log(2^-150) or nan
+ if (xbits.uintval() >= 0xc2cf'f1b5U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ return 0.0f;
+ }
+ // x >= 89 or nan
+ if (xbits.is_pos() && (xbits.uintval() >= 0x42b2'0000)) {
+ // x is finite
+ if (xbits.uintval() < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ }
+ // For -104 < x < 89, to compute exp(x), we perform the following range
+ // reduction: find hi, mid, lo such that:
+ // x = hi + mid + lo, in which
+ // hi is an integer,
+ // mid * 2^7 is an integer
+ // -2^(-8) <= lo < 2^-8.
+ // In particular,
+ // hi + mid = round(x * 2^7) * 2^(-7).
+ // Then,
+ // exp(x) = exp(hi + mid + lo) = exp(hi) * exp(mid) * exp(lo).
+ // We store exp(hi) and exp(mid) in the lookup tables EXP_M1 and EXP_M2
+ // respectively. exp(lo) is computed using a degree-4 minimax polynomial
+ // generated by Sollya.
+
+ // x_hi = (hi + mid) * 2^7 = round(x * 2^7).
+ float kf = fputil::nearest_integer(x * 0x1.0p7f);
+ // Subtract (hi + mid) from x to get lo.
+ double xd = static_cast<double>(fputil::multiply_add(kf, -0x1.0p-7f, x));
+ int x_hi = static_cast<int>(kf);
+ x_hi += 104 << 7;
+ // hi = x_hi >> 7
+ double exp_hi = EXP_M1[x_hi >> 7];
+ // mid * 2^7 = x_hi & 0x0000'007fU;
+ double exp_mid = EXP_M2[x_hi & 0x7f];
+ // Degree-4 minimax polynomial generated by Sollya with the following
+ // commands:
+ // > display = hexadecimal;
+ // > Q = fpminimax(expm1(x)/x, 3, [|D...|], [-2^-8, 2^-8]);
+ // > Q;
+ double exp_lo =
+ fputil::polyeval(xd, 0x1p0, 0x1.ffffffffff777p-1, 0x1.000000000071cp-1,
+ 0x1.555566668e5e7p-3, 0x1.55555555ef243p-5);
+ return static_cast<float>(exp_hi * exp_mid * exp_lo);
+}
+
+} // namespace double_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_DOUBLE_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_float_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_float_eval.h
new file mode 100644
index 00000000000..e479cb58d2f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_float_eval.h
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Float-only implementation of expf.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_FLOAT_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_FLOAT_EVAL_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/exp2f_float_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace float_eval {
+
+LIBC_INLINE float expf(float x) {
+ using FPBits = fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ // When |x| >= 89, |x| < 2^-25, or x is nan
+ if (LIBC_UNLIKELY(x_abs >= 0x42b2'0000U || x_abs <= 0x3280'0000U)) {
+ // |x| < 2^-25
+ if (xbits.get_biased_exponent() <= 101) {
+ return 1.0f + x;
+ }
+
+ // When x < log(2^-150) or nan
+ if (xbits.uintval() >= 0xc2cf'f1b5U) {
+ // exp(-Inf) = 0
+ if (xbits.is_inf())
+ return 0.0f;
+ // exp(nan) = nan
+ if (xbits.is_nan())
+ return x;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (fputil::fenv_is_round_up())
+ return FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_UNDERFLOW);
+ return 0.0f;
+ }
+ // x >= 89 or nan
+ if (xbits.is_pos() && (xbits.uintval() >= 0x42b2'0000)) {
+ // x is finite
+ if (xbits.uintval() < 0x7f80'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+ }
+ // x is +inf or nan
+ return x + FPBits::inf().get_val();
+ }
+ }
+
+ // Range reduction:
+ // k = round(x * log2(e))
+ // x * log2(e) = k + u, with |u| <= 0.5
+ // e^x = 2^(k + u) = 2^k * 2^u
+#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
+ // Constants generated by Sollya with:
+ // > display = hexadecimal;
+ // > hi = round(log2(exp(1)), SG, RN);
+ // > lo = round(log2(exp(1)) - hi, SG, RN);
+ constexpr fputil::FloatFloat LOG2_E = {/*lo=*/0x1.4ae0cp-26f,
+ /*hi=*/0x1.715476p+0f};
+
+ float kf = fputil::nearest_integer(x * LOG2_E.hi);
+ int k = static_cast<int>(kf);
+
+ float u_hi = fputil::multiply_add(x, LOG2_E.hi, -kf);
+ float u = fputil::multiply_add(x, LOG2_E.lo, u_hi);
+#else // !LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ // Cody-Waite reduction for non-FMA targets:
+ // Constants generated by Sollya with:
+ // > display = hexadecimal;
+ // > LOG2_E = round(log2(exp(1)), SG, RN);
+ // > LOG_2_HI = round(log(2), 12, RN);
+ // > LOG_2_LO = round(log(2) - LOG_2_HI, SG, RN);
+ constexpr float LOG2_E = 0x1.715476p+0f;
+ constexpr float LOG_2_HI = 0x1.62ep-1f;
+ constexpr float LOG_2_LO = 0x1.0bfbe8p-15f;
+
+ float kf = fputil::nearest_integer(x * LOG2_E);
+ int k = static_cast<int>(kf);
+
+ float v_hi = fputil::multiply_add(-kf, LOG_2_HI, x);
+ float v = fputil::multiply_add(-kf, LOG_2_LO, v_hi);
+
+ // Convert reduced argument to base-2: u = v * log2(e)
+ float u = v * LOG2_E;
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+
+ return exp2f_eval(u, k);
+}
+
+} // namespace float_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_FLOAT_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_integer_eval.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_integer_eval.h
index e48b459f880..52736323d8d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_integer_eval.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_integer_eval.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_INTEGER_EVAL_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_INTEGER_EVAL_H
+#include "hdr/fenv_macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -58,7 +59,7 @@ LIBC_INLINE_VAR constexpr Frac64 EXPF_COEFFS[] = {
// Statically rounded, no except implementation of expf using integer-only
// arithmetic.
LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
- using FPBits = typename fputil::FPBits<float>;
+ using FPBits = fputil::FPBits<float>;
using FPBounds = LIBC_NAMESPACE::math::check::exp_internal::Bounds<float>;
FPBits xbits(x);
@@ -74,7 +75,7 @@ LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
if (x_val_abs <= 0x3300'0000U) {
#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
return 1.0f;
-#else
+#else // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
if (x_val_abs == 0)
return 1.0f;
@@ -113,7 +114,7 @@ LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
return FPBits::max_normal().get_val();
return FPBits::inf().get_val();
-#else
+#else // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
return FPBits::inf().get_val();
#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
}
@@ -248,7 +249,7 @@ LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
result += e_y_unbiased;
return cpp::bit_cast<float>(result);
-#else
+#else // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
if (rounding == FE_TONEAREST) {
uint32_t result =
(static_cast<uint32_t>(p.val[0] >> shift_length) + (leading_one + 1));
@@ -270,7 +271,7 @@ LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
result += e_y_unbiased;
return cpp::bit_cast<float>(result);
-#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
}
} // namespace static_rounding
@@ -279,6 +280,16 @@ LIBC_INLINE float expf(float x, [[maybe_unused]] int rounding) {
} // namespace shared
+namespace math {
+namespace integer_eval {
+
+LIBC_INLINE float expf(float x) {
+ return shared::math::static_rounding::expf(x, FE_TONEAREST);
+}
+
+} // namespace integer_eval
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_INTEGER_EVAL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fabsf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fabsf128.h
index 242c91ff8e3..78c68e58ad8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fabsf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fabsf128.h
@@ -9,21 +9,18 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FABSF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FABSF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fabsf128(float128 x) { return fputil::abs(x); }
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fabsf128(Float128 x) { return fputil::abs(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FABSF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fdimf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fdimf128.h
index 0f73f1c0561..63b3913fb7a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fdimf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fdimf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FDIMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FDIMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fdimf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fdimf128(Float128 x, Float128 y) {
return fputil::fdim(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FDIMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_mag_numf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_mag_numf128.h
index 79e8842f81e..d0aaeae0327 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_mag_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_mag_numf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAG_NUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAG_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fmaximum_mag_numf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fmaximum_mag_numf128(Float128 x, Float128 y) {
return fputil::fmaximum_mag_num(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAG_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_magf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_magf128.h
index b540e0940c9..11b0385061b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_magf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_magf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAGF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fmaximum_magf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fmaximum_magf128(Float128 x, Float128 y) {
return fputil::fmaximum_mag(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_MAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_numf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_numf128.h
index ccee570de2c..f81f8512015 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximum_numf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_NUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fmaximum_numf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fmaximum_numf128(Float128 x, Float128 y) {
return fputil::fmaximum_num(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUM_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximumf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximumf128.h
index 136b16419cd..91326ef2788 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximumf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaximumf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fmaximumf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fmaximumf128(Float128 x, Float128 y) {
return fputil::fmaximum(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXIMUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_mag_numf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_mag_numf128.h
index d8b23a38247..b02f388f4a8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_mag_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_mag_numf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAG_NUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAG_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fminimum_mag_numf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fminimum_mag_numf128(Float128 x, Float128 y) {
return fputil::fminimum_mag_num(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAG_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_magf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_magf128.h
index ea571905fb7..d81f64821da 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_magf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_magf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAGF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fminimum_magf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fminimum_magf128(Float128 x, Float128 y) {
return fputil::fminimum_mag(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_MAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_numf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_numf128.h
index 6f3ac894a7d..607eae7ee0e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_numf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimum_numf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_NUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_NUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fminimum_numf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fminimum_numf128(Float128 x, Float128 y) {
return fputil::fminimum_num(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUM_NUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimumf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimumf128.h
index cfbe36ba1fb..6a6ed675ffa 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimumf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminimumf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUMF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUMF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 fminimumf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fminimumf128(Float128 x, Float128 y) {
return fputil::fminimum(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMINIMUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow.h
index c03e6be271d..75125d78962 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow.h
@@ -1,368 +1,167 @@
-//===-- Implementation header for pow ---------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for double-precision pow(x, y).
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POW_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_POW_H
-#include "common_constants.h" // Lookup tables EXP_M1 and EXP_M2.
-#include "exp_constants.h" // Lookup tables EXP_M1 and EXP_M2.
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/CPP/bit.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/FPUtil/sqrt.h" // Speedup for pow(x, 1/2) = sqrt(x)
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/common_constants.h"
+#include "src/__support/math/exp_constants.h"
+#include "src/__support/math/pow_utils.h"
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#include "src/__support/math/pow_fast.h"
+#else
+
+#include "src/__support/math/pow_accurate_128.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-namespace pow_internal {
-
-using fputil::DoubleDouble;
-
-using namespace common_constants_internal;
-
-// Constants for log2(x) range reduction, generated by Sollya with:
-// > for i from 0 to 127 do {
-// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^-7) );
-// b = nearestint(log2(r) * 2^41) * 2^-41;
-// c = round(log2(r) - b, D, RN);
-// print("{", -c, ",", -b, "},");
-// };
-// This is the same as -log2(RD[i]), with the least significant bits of the
-// high part set to be 2^-41, so that the sum of high parts + e_x is exact in
-// double precision.
-// We also replace the first and the last ones to be 0.
-LIBC_INLINE_VAR constexpr DoubleDouble LOG2_R_DD[128] = {
- {0.0, 0.0},
- {-0x1.19b14945cf6bap-44, 0x1.72c7ba21p-7},
- {-0x1.95539356f93dcp-43, 0x1.743ee862p-6},
- {0x1.abe0a48f83604p-43, 0x1.184b8e4c5p-5},
- {0x1.635577970e04p-43, 0x1.77394c9d9p-5},
- {-0x1.401fbaaa67e3cp-45, 0x1.d6ebd1f2p-5},
- {-0x1.5b1799ceaeb51p-43, 0x1.1bb32a6008p-4},
- {0x1.7c407050799bfp-43, 0x1.4c560fe688p-4},
- {0x1.da6339da288fcp-43, 0x1.7d60496cf8p-4},
- {0x1.be4f6f22dbbadp-43, 0x1.960caf9ab8p-4},
- {-0x1.c760bc9b188c4p-45, 0x1.c7b528b71p-4},
- {0x1.164e932b2d51cp-44, 0x1.f9c95dc1dp-4},
- {0x1.924ae921f7ecap-45, 0x1.097e38ce6p-3},
- {-0x1.6d25a5b8a19b2p-44, 0x1.22dadc2ab4p-3},
- {0x1.e50a1644ac794p-43, 0x1.3c6fb650ccp-3},
- {0x1.f34baa74a7942p-43, 0x1.494f863b8cp-3},
- {-0x1.8f7aac147fdc1p-46, 0x1.633a8bf438p-3},
- {0x1.f84be19cb9578p-43, 0x1.7046031c78p-3},
- {-0x1.66cccab240e9p-46, 0x1.8a8980abfcp-3},
- {-0x1.3f7a55cd2af4cp-47, 0x1.97c1cb13c8p-3},
- {0x1.3458cde69308cp-43, 0x1.b2602497d4p-3},
- {-0x1.667f21fa8423fp-44, 0x1.bfc67a8p-3},
- {0x1.d2fe4574e09b9p-47, 0x1.dac22d3e44p-3},
- {0x1.367bde40c5e6dp-43, 0x1.e857d3d36p-3},
- {0x1.d45da26510033p-46, 0x1.01d9bbcfa6p-2},
- {-0x1.7204f55bbf90dp-44, 0x1.08bce0d96p-2},
- {-0x1.d4f1b95e0ff45p-43, 0x1.169c05364p-2},
- {0x1.c20d74c0211bfp-44, 0x1.1d982c9d52p-2},
- {0x1.ad89a083e072ap-43, 0x1.249cd2b13cp-2},
- {0x1.cd0cb4492f1bcp-43, 0x1.32bfee370ep-2},
- {-0x1.2101a9685c779p-47, 0x1.39de8e155ap-2},
- {0x1.9451cd394fe8dp-43, 0x1.4106017c3ep-2},
- {0x1.661e393a16b95p-44, 0x1.4f6fbb2cecp-2},
- {-0x1.c6d8d86531d56p-44, 0x1.56b22e6b58p-2},
- {0x1.c1c885adb21d3p-43, 0x1.5dfdcf1eeap-2},
- {0x1.3bb5921006679p-45, 0x1.6552b49986p-2},
- {0x1.1d406db502403p-43, 0x1.6cb0f6865cp-2},
- {0x1.55a63e278bad5p-43, 0x1.7b89f02cf2p-2},
- {-0x1.66ae2a7ada553p-49, 0x1.8304d90c12p-2},
- {-0x1.66cccab240e9p-45, 0x1.8a8980abfcp-2},
- {-0x1.62404772a151dp-45, 0x1.921800924ep-2},
- {0x1.ac9bca36fd02ep-44, 0x1.99b072a96cp-2},
- {0x1.4bc302ffa76fbp-43, 0x1.a8ff97181p-2},
- {0x1.01fea1ec47c71p-43, 0x1.b0b67f4f46p-2},
- {-0x1.f20203b3186a6p-43, 0x1.b877c57b1cp-2},
- {-0x1.2642415d47384p-45, 0x1.c043859e3p-2},
- {-0x1.bc76a2753b99bp-50, 0x1.c819dc2d46p-2},
- {-0x1.da93ae3a5f451p-43, 0x1.cffae611aep-2},
- {-0x1.50e785694a8c6p-43, 0x1.d7e6c0abc4p-2},
- {0x1.c56138c894641p-43, 0x1.dfdd89d586p-2},
- {0x1.5669df6a2b592p-43, 0x1.e7df5fe538p-2},
- {-0x1.ea92d9e0e8ac2p-48, 0x1.efec61b012p-2},
- {0x1.a0331af2e6feap-43, 0x1.f804ae8d0cp-2},
- {0x1.9518ce032f41dp-48, 0x1.0014332bep-1},
- {-0x1.b3b3864c60011p-44, 0x1.042bd4b9a8p-1},
- {-0x1.103e8f00d41c8p-45, 0x1.08494c66b9p-1},
- {0x1.65be75cc3da17p-43, 0x1.0c6caaf0c5p-1},
- {0x1.3676289cd3dd4p-43, 0x1.1096015deep-1},
- {-0x1.41dfc7d7c3321p-43, 0x1.14c560fe69p-1},
- {0x1.e0cda8bd74461p-44, 0x1.18fadb6e2dp-1},
- {0x1.2a606046ad444p-44, 0x1.1d368296b5p-1},
- {0x1.f9ea977a639cp-43, 0x1.217868b0c3p-1},
- {-0x1.50520a377c7ecp-45, 0x1.25c0a0463cp-1},
- {0x1.6e3cb71b554e7p-47, 0x1.2a0f3c3407p-1},
- {-0x1.4275f1035e5e8p-48, 0x1.2e644fac05p-1},
- {-0x1.4275f1035e5e8p-48, 0x1.2e644fac05p-1},
- {-0x1.979a5db68721dp-45, 0x1.32bfee370fp-1},
- {0x1.1ee969a95f529p-43, 0x1.37222bb707p-1},
- {0x1.bb4b69336b66ep-43, 0x1.3b8b1c68fap-1},
- {0x1.d5e6a8a4fb059p-45, 0x1.3ffad4e74fp-1},
- {0x1.3106e404cabb7p-44, 0x1.44716a2c08p-1},
- {0x1.3106e404cabb7p-44, 0x1.44716a2c08p-1},
- {-0x1.9bcaf1aa4168ap-43, 0x1.48eef19318p-1},
- {0x1.1646b761c48dep-44, 0x1.4d7380dcc4p-1},
- {0x1.2f0c0bfe9dbecp-43, 0x1.51ff2e3021p-1},
- {0x1.29904613e33cp-43, 0x1.5692101d9bp-1},
- {0x1.1d406db502403p-44, 0x1.5b2c3da197p-1},
- {0x1.1d406db502403p-44, 0x1.5b2c3da197p-1},
- {-0x1.125d6cbcd1095p-44, 0x1.5fcdce2728p-1},
- {-0x1.bd9b32266d92cp-43, 0x1.6476d98adap-1},
- {0x1.54243b21709cep-44, 0x1.6927781d93p-1},
- {0x1.54243b21709cep-44, 0x1.6927781d93p-1},
- {-0x1.ce60916e52e91p-44, 0x1.6ddfc2a79p-1},
- {0x1.f1f5ae718f241p-43, 0x1.729fd26b7p-1},
- {-0x1.6eb9612e0b4f3p-43, 0x1.7767c12968p-1},
- {-0x1.6eb9612e0b4f3p-43, 0x1.7767c12968p-1},
- {0x1.fed21f9cb2cc5p-43, 0x1.7c37a9227ep-1},
- {0x1.7f5dc57266758p-43, 0x1.810fa51bf6p-1},
- {0x1.7f5dc57266758p-43, 0x1.810fa51bf6p-1},
- {0x1.5b338360c2ae2p-43, 0x1.85efd062c6p-1},
- {-0x1.96fc8f4b56502p-43, 0x1.8ad846cf37p-1},
- {-0x1.96fc8f4b56502p-43, 0x1.8ad846cf37p-1},
- {-0x1.bdc81c4db3134p-44, 0x1.8fc924c89bp-1},
- {0x1.36c101ee1344p-43, 0x1.94c287492cp-1},
- {0x1.36c101ee1344p-43, 0x1.94c287492cp-1},
- {0x1.e41fa0a62e6aep-44, 0x1.99c48be206p-1},
- {-0x1.d97ee9124773bp-46, 0x1.9ecf50bf44p-1},
- {-0x1.d97ee9124773bp-46, 0x1.9ecf50bf44p-1},
- {-0x1.3f94e00e7d6bcp-46, 0x1.a3e2f4ac44p-1},
- {-0x1.6879fa00b120ap-43, 0x1.a8ff971811p-1},
- {-0x1.6879fa00b120ap-43, 0x1.a8ff971811p-1},
- {0x1.1659d8e2d7d38p-44, 0x1.ae255819fp-1},
- {0x1.1e5e0ae0d3f8ap-43, 0x1.b35458761dp-1},
- {0x1.1e5e0ae0d3f8ap-43, 0x1.b35458761dp-1},
- {0x1.484a15babcf88p-43, 0x1.b88cb9a2abp-1},
- {0x1.484a15babcf88p-43, 0x1.b88cb9a2abp-1},
- {0x1.871a7610e40bdp-45, 0x1.bdce9dcc96p-1},
- {-0x1.2d90e5edaeceep-43, 0x1.c31a27dd01p-1},
- {-0x1.2d90e5edaeceep-43, 0x1.c31a27dd01p-1},
- {-0x1.5dd31d962d373p-43, 0x1.c86f7b7ea5p-1},
- {-0x1.5dd31d962d373p-43, 0x1.c86f7b7ea5p-1},
- {-0x1.9ad57391924a7p-43, 0x1.cdcebd2374p-1},
- {-0x1.3167ccc538261p-44, 0x1.d338120a6ep-1},
- {-0x1.3167ccc538261p-44, 0x1.d338120a6ep-1},
- {0x1.c7a4ff65ddbc9p-45, 0x1.d8aba045bp-1},
- {0x1.c7a4ff65ddbc9p-45, 0x1.d8aba045bp-1},
- {-0x1.f9ab3cf74babap-44, 0x1.de298ec0bbp-1},
- {-0x1.f9ab3cf74babap-44, 0x1.de298ec0bbp-1},
- {0x1.52842c1c1e586p-43, 0x1.e3b20546f5p-1},
- {0x1.52842c1c1e586p-43, 0x1.e3b20546f5p-1},
- {0x1.3c6764fc87b4ap-48, 0x1.e9452c8a71p-1},
- {0x1.3c6764fc87b4ap-48, 0x1.e9452c8a71p-1},
- {-0x1.a0976c0a2827dp-44, 0x1.eee32e2aedp-1},
- {-0x1.a0976c0a2827dp-44, 0x1.eee32e2aedp-1},
- {-0x1.a45314dc4fc42p-43, 0x1.f48c34bd1fp-1},
- {-0x1.a45314dc4fc42p-43, 0x1.f48c34bd1fp-1},
- {0x1.ef5d00e390ap-44, 0x1.fa406bd244p-1},
- {0.0, 1.0},
-};
-
-LIBC_INLINE bool is_odd_integer(double x) {
- using FPBits = fputil::FPBits<double>;
- FPBits xbits(x);
- uint64_t x_u = xbits.uintval();
- unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
- unsigned lsb =
- static_cast<unsigned>(cpp::countr_zero(x_u | FPBits::EXP_MASK));
- constexpr unsigned UNIT_EXPONENT =
- static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
- return (x_e + lsb == UNIT_EXPONENT);
-}
-
-LIBC_INLINE bool is_integer(double x) {
- using FPBits = fputil::FPBits<double>;
- FPBits xbits(x);
- uint64_t x_u = xbits.uintval();
- unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
- unsigned lsb =
- static_cast<unsigned>(cpp::countr_zero(x_u | FPBits::EXP_MASK));
- constexpr unsigned UNIT_EXPONENT =
- static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
- return (x_e + lsb >= UNIT_EXPONENT);
-}
-
-} // namespace pow_internal
+// Overview of the main part of pow(x, y) = x^y computations.
+//
+// Let x = 2^(e_x) * m_x > 0. Then:
+// x^y = 2^( y * log2(x) )
+// = 2^( y * ( e_x + log2(m_x) ) )
+// = 2^( e_h + e_l )
+// = 2^(e_h) * 2^(e_l)
+// where:
+// e_h = round(y * log2(x)),
+// e_l = {y * log2(x)} = y * log2(x) - e_h.
+//
+// In particular, e_h is an integer, and |e_l| <= 0.5.
+//
+// For the final result to be fit in double precision, the exponent field can be
+// bounded by:
+// -1075 <= e_h <= 1024,
+// and anything outside that can be passed to quick overflow/underflow logic.
+//
+// Since |e_l| <= 0.5:
+// 0.5 < 2^(e_l) < 2,
+// the relative error of x^y = 2^(e_h) * 2^(e_l) is about
+// ~ absolute error of e_l
+// ~ absolute error of y * log2(x)
+// ~ relative error(log2(x)) * |y|
+// ~ relative error(log2(x)) * |e_h|
+// < relative error(log2(x)) * 2^11.
+//
+// Roughly speaking, to compute x^y with relative error < 2^(-n), we will need
+// to compute log2(x) with relative error < 2^(-n - 11), approximately.
+//
+// To compute log2(x), we will perform range reduction for log2(m_x):
+// dx = r * m_x - 1.
+// Then m_x = (1 + dx) / r, and
+// log2(m_x) = log2( (1 + dx) / r )
+// = log2(1 + dx) - log2(r),
+// where -log2(r) is obtained from look up tables.
+// The computation of dx = r * m_x - 1 is exact, and we choose the size of the
+// look up table for r's such that:
+// -2^-8 <= dx < 2^-7.
+// Combining them together, we have that:
+// log2(x) = e_x - log2(r) + log2(1 + dx)
+// = e_x - log2(r) + log2(e) * (dx - dx^2/2 + dx^3/3 - ...)
+// So in the worst case, where e_x = log2(r) = 0, the relative error of log2(x)
+// computation will be:
+// ~ absolute_error(log2(1 + dx)) / |dx|.
+// So if we compute log2(1 + dx) accurately up to dx^n term, and use a
+// polynomial approximation for the dx^(n + 1) and higher terms:
+// log2(1 + dx) ~ log2(e) * (dx - dx^2/2 + ... + (-1)^(n + 1) dx^n / n) +
+// dx^(n + 1) * P(dx)
+// such that the absolute error of P(dx) is smaller than double precision ulp,
+// then the overall relative error of our log2(1 + dx) approximation is:
+// ~ ulp(dx^(n + 1)) / |dx| ~ 2^(-52) * |dx^n|
+//
+// Let's consider 3 cases:
+// - For a fast path of a correctly rounded implementation, we will want the
+// relative error of x^y bounded above by:
+// ~ 2^(-precision - 10) = 2^(-53 - 10) = 2^(-63)
+// so that the Ziv accuracy test passes with probability > 1 - 2^-10 ~ 99.99%.
+// And from the above argument, we need to compute log2(1 + dx) with relative
+// error ~ 2^(-63 - 11) = 2^(-74).
+// So we will need to compute log2(1 + dx) accurately up to dx^n such that:
+// 2^(-52) * |dx^n| ~ 2^(-74).
+// Or equivalently:
+// |dx^n| < 2^(-22).
+// With our bounds from range reduction |dx| < 2^(-7), n = 3 will be quite
+// close to our desired precision needed.
+//
+// In summary, for a fast path of correctly rounded implementation, we will
+// compute log2(e) * (dx - dx^2/2 + dx^3/3) accurately, and approximate higher
+// terms with dx^4 * P(dx), where:
+// |(log2(1 + dx) - log2(e) * (dx - dx^2/2 + dx^3/3))/dx^4 - P(dx)| < 2^-53.
+//
+// - For a strictly < 1 ULP error fast version across the full exponent range
+// (as implemented in pow_fast), we will want the relative error of x^y
+// bounded above by:
+// ~ 2^(-precision) = 2^(-53).
+// So the relative error needed to approximate log2(1 + dx) is:
+// ~ 2^(-53 - 11) = 2^(-64),
+// and we will need to compute log2(1 + dx) accurately up to dx^n such that:
+// 2^(-52) * |dx^n| ~ 2^(-64),
+// or equivalently:
+// |dx^n| < 2^-12.
+// With |dx| < 2^(-7), n = 2 satisfies |dx^2| < 2^(-14) < 2^(-12).
+// Hence, we compute log2(e) * (dx - dx^2/2) accurately in DoubleDouble, and
+// approximate higher terms with dx^3 * P(dx), where:
+// |(log2(1 + dx) - log2(e) * (dx - dx^2/2))/dx^3 - P(dx)| < 2^-53.
+// This guarantees error < 1 ULP everywhere (empirically bounded by 0.75 ULP).
+//
+// - If we were to choose n = 1 (computing only log2(e) * dx accurately, and
+// approximating higher terms with dx^2 * P(dx)), the relative error of
+// log2(1 + dx) is only bounded by:
+// ~ 2^(-52) * |dx| < 2^(-52) * 2^(-7) = 2^(-59).
+// The resulting relative error of x^y is about:
+// ~ 2^(-59) * |e_h|.
+// While this achieves < 1 ULP for typical inputs with |e_h| <= 64, near
+// extreme exponent boundaries (|e_h| ~ 2^10 and |dx| ~ 2^-7) the error can
+// drift up to ~7.8 ULPs (bounded theoretically by ~16 ULPs).
LIBC_INLINE double pow(double x, double y) {
using namespace pow_internal;
using FPBits = fputil::FPBits<double>;
FPBits xbits(x), ybits(y);
-
- bool x_sign = xbits.sign() == Sign::NEG;
- bool y_sign = ybits.sign() == Sign::NEG;
-
- FPBits x_abs = xbits.abs();
- FPBits y_abs = ybits.abs();
-
- uint64_t x_mant = xbits.get_mantissa();
- uint64_t y_mant = ybits.get_mantissa();
uint64_t x_u = xbits.uintval();
- uint64_t x_a = x_abs.uintval();
- uint64_t y_a = y_abs.uintval();
-
- double e_x = static_cast<double>(xbits.get_exponent());
- uint64_t sign = 0;
+ uint64_t y_u = ybits.uintval();
+ uint64_t y_a = ybits.abs().uintval();
- ///////// BEGIN - Check exceptional cases ////////////////////////////////////
- // If x or y is signaling NaN
- if (x_abs.is_signaling_nan() || y_abs.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
+ if (LIBC_UNLIKELY((x_u & 0x0003'FFFF'FFFF'FFFF) == 0 ||
+ (y_u & 0x000F'FFFF'FFFF'FFFF) == 0)) {
+ if (auto r = check_special_inputs(x, y); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
}
- // The double precision number that is closest to 1 is (1 - 2^-53), which has
- // log2(1 - 2^-53) ~ -1.715...p-53.
- // So if |y| > |1075 / log2(1 - 2^-53)|, and x is finite:
- // |y * log2(x)| = 0 or > 1075.
- // Hence x^y will either overflow or underflow if x is not zero.
- if (LIBC_UNLIKELY(y_mant == 0 || y_a > 0x43d7'4910'd52d'3052 ||
- x_u == FPBits::one().uintval() ||
+ double e_x = static_cast<double>(xbits.get_exponent());
+ uint64_t x_mant = xbits.get_mantissa();
+ bool is_neg = false;
+ double sign_d = 1.0;
+
+ if (LIBC_UNLIKELY(y_a <= Y_LOWER_BOUND || y_a >= Y_UPPER_BOUND ||
x_u >= FPBits::inf().uintval() ||
x_u < FPBits::min_normal().uintval())) {
- // Exceptional exponents.
- if (y == 0.0)
- return 1.0;
-
- switch (y_a) {
- case 0x3fe0'0000'0000'0000: { // y = +-0.5
- // TODO: speed up x^(-1/2) with rsqrt(x) when available.
- if (LIBC_UNLIKELY(
- (x == 0.0 || x_u == FPBits::inf(Sign::NEG).uintval()))) {
- // pow(-0, 1/2) = +0
- // pow(-inf, 1/2) = +inf
- // Make sure it works correctly for FTZ/DAZ.
- return y_sign ? 1.0 / (x * x) : (x * x);
- }
- return y_sign ? (1.0 / fputil::sqrt<double>(x)) : fputil::sqrt<double>(x);
- }
- case 0x3ff0'0000'0000'0000: // y = +-1.0
- return y_sign ? (1.0 / x) : x;
- case 0x4000'0000'0000'0000: // y = +-2.0;
- return y_sign ? (1.0 / (x * x)) : (x * x);
- }
-
- // |y| > |1075 / log2(1 - 2^-53)|.
- if (y_a > 0x43d7'4910'd52d'3052) {
- if (y_a >= 0x7ff0'0000'0000'0000) {
- // y is inf or nan
- if (y_mant != 0) {
- // y is NaN
- // pow(1, NaN) = 1
- // pow(x, NaN) = NaN
- return (x_u == FPBits::one().uintval()) ? 1.0 : y;
- }
-
- // Now y is +-Inf
- if (x_abs.is_nan()) {
- // pow(NaN, +-Inf) = NaN
- return x;
- }
-
- if (x_a == 0x3ff0'0000'0000'0000) {
- // pow(+-1, +-Inf) = 1.0
- return 1.0;
- }
-
- if (x == 0.0 && y_sign) {
- // pow(+-0, -Inf) = +inf and raise FE_DIVBYZERO
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_DIVBYZERO);
- return FPBits::inf().get_val();
- }
- // pow (|x| < 1, -inf) = +inf
- // pow (|x| < 1, +inf) = 0.0
- // pow (|x| > 1, -inf) = 0.0
- // pow (|x| > 1, +inf) = +inf
- return ((x_a < FPBits::one().uintval()) == y_sign)
- ? FPBits::inf().get_val()
- : 0.0;
- }
- // x^y will overflow / underflow in double precision. Set y to a
- // large enough exponent but not too large, so that the computations
- // won't overflow in double precision.
- y = y_sign ? -0x1.0p100 : 0x1.0p100;
- }
-
- // y is finite and non-zero.
-
- if (x_u == FPBits::one().uintval()) {
- // pow(1, y) = 1
- return 1.0;
- }
-
- // TODO: Speed things up with pow(2, y) = exp2(y) and pow(10, y) = exp10(y).
-
- if (x == 0.0) {
- bool out_is_neg = x_sign && is_odd_integer(y);
- if (y_sign) {
- // pow(0, negative number) = inf
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_DIVBYZERO);
- return FPBits::inf(out_is_neg ? Sign::NEG : Sign::POS).get_val();
- }
- // pow(0, positive number) = 0
- return out_is_neg ? -0.0 : 0.0;
- }
-
- if (x_a == FPBits::inf().uintval()) {
- bool out_is_neg = x_sign && is_odd_integer(y);
- if (y_sign)
- return out_is_neg ? -0.0 : 0.0;
- return FPBits::inf(out_is_neg ? Sign::NEG : Sign::POS).get_val();
- }
-
- if (x_a > FPBits::inf().uintval()) {
- // x is NaN.
- // pow (aNaN, 0) is already taken care above.
- return x;
- }
-
- // Normalize denormal inputs.
- if (x_a < FPBits::min_normal().uintval()) {
- FPBits x_norm(x * 0x1.0p64);
- e_x = static_cast<double>(x_norm.get_exponent()) - 64.0;
- x_mant = x_norm.get_mantissa();
- }
-
- // x is finite and negative, and y is a finite integer.
- if (x_sign) {
- if (is_integer(y)) {
- x = -x;
- if (is_odd_integer(y))
- // sign = -1.0;
- sign = 0x8000'0000'0000'0000;
- } else {
- // pow( negative, non-integer ) = NaN
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- }
+ if (auto r = check_exceptional_cases(x, y, e_x, x_mant, is_neg, sign_d);
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
}
- ///////// END - Check exceptional cases //////////////////////////////////////
-
// x^y = 2^( y * log2(x) )
// = 2^( y * ( e_x + log2(m_x) ) )
// First we compute log2(x) = e_x + log2(m_x)
@@ -382,66 +181,90 @@ LIBC_INLINE double pow(double x, double y) {
// log2(m_x) = log2( (1 + dx) / r )
// = log2(1 + dx) - log2(r).
- // In order for the overall computations x^y = 2^(y * log2(x)) to have the
- // relative errors < 2^-52 (1ULP), we will need to evaluate the exponent part
- // y * log2(x) with absolute errors < 2^-52 (or better, 2^-53). Since the
- // whole exponent range for double precision is bounded by
- // |y * log2(x)| < 1076 ~ 2^10, we need to evaluate log2(x) with absolute
- // errors < 2^-53 * 2^-10 = 2^-63.
+ // As analyzed in the overview comment above, we evaluate the cubic part
+ // (dx * C1 + dx^2 * C2 + dx^3 * C3) accurately using DoubleDouble (n = 3)
+ // and approximate higher terms with dx^4 * P(dx) to ensure relative error
+ // < 2^-63 for this fast path.
- // With that requirement, we use the following degree-6 polynomial
- // approximation:
- // P(dx) ~ log2(1 + dx) / dx
+ // Degree-5 polynomial approximation for:
+ // P(dx) ~ (log2(1 + dx) - (dx - dx^2/2 + dx^3/3)/log(2)) / dx^4
// Generated by Sollya with:
- // > P = fpminimax(log2(1 + x)/x, 6, [|D...|], [-2^-8, 2^-7]); P;
- // > dirtyinfnorm(log2(1 + x) - x*P, [-2^-8, 2^-7]);
- // 0x1.d03cc...p-66
- constexpr double COEFFS[] = {0x1.71547652b82fep0, -0x1.71547652b82e7p-1,
- 0x1.ec709dc3b1fd5p-2, -0x1.7154766124215p-2,
- 0x1.2776bd90259d8p-2, -0x1.ec586c6f3d311p-3,
- 0x1.9c4775eccf524p-3};
- // Error: ulp(dx^2) <= (2^-7)^2 * 2^-52 = 2^-66
- // Extra errors from various computations and rounding directions, the overall
- // errors we can be bounded by 2^-65.
-
- DoubleDouble dx_c0;
-
- // Perform exact range reduction and exact product dx * c0.
+ // > P = fpminimax((log2(1 + x) - (x - x^2/2 + x^3/3)/log(2))/x^4, 5,
+ // [|D...|], [-2^-8, 2^-7]);
+ // > dirtyinfnorm((log2(1 + x) - (x - x^2/2 + x^3/3)/log(2))/x - x^3*P,
+ // [-2^-8, 2^-7]);
+ // 0x1.a643c...p-74
+ // > dirtyinfnorm((log2(1 + x) - (x - x^2/2 + x^3/3)/log(2))/x^4 - P,
+ // [-2^-8, 2^-7]);
+ // 0x1.b81c5...p-53
+ constexpr double COEFFS[] = {-0x1.71547652b82fdp-2, 0x1.2776c50ef8f9bp-2,
+ -0x1.ec709dc4f0fedp-3, 0x1.a617677f716dep-3,
+ -0x1.715423d54d5p-3, 0x1.44e6355fc4d03p-3};
+
+ // Constants for C_k = (-1)^(k-1) / (k * log(2)) in DoubleDouble:
+ // C1 = 1 / log(2)
+ constexpr DoubleDouble C1 = {0x1.777d0ffda0d24p-56, 0x1.71547652b82fep0};
+ // C2 = -1 / (2 * log(2))
+ constexpr DoubleDouble C2 = {-0x1.777d0ffda0d24p-57, -0x1.71547652b82fep-1};
+ // C3 = 1 / (3 * log(2))
+ constexpr DoubleDouble C3 = {0x1.b749fc15522bcp-50, 0x1.ec709dc3a03e2p-2};
+
+ // Perform exact range reduction.
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
double dx = fputil::multiply_add(RD[idx_x], m_x.get_val(), -1.0); // Exact
- dx_c0 = fputil::exact_mult(COEFFS[0], dx);
#else
double c = FPBits(m_x.uintval() & 0x3fff'e000'0000'0000).get_val();
double dx =
fputil::multiply_add(RD[idx_x], m_x.get_val() - c, CD[idx_x]); // Exact
- dx_c0 = fputil::exact_mult<double, 28>(dx, COEFFS[0]); // Exact
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ // Evaluate the cubic part (dx * C1 + dx^2 * C2 + dx^3 * C3) and polynomial
+ // tail using a parallel Double-Double Estrin scheme.
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ // Error-free transformation for r = C1.hi + dx * C2.hi:
+ double r_hi = fputil::multiply_add(dx, C2.hi, C1.hi);
+ double r_lo = fputil::multiply_add(dx, C2.hi, C1.hi - r_hi); // Exact error
+#else
+ DoubleDouble dx_c2 = fputil::exact_mult(dx, C2.hi);
+ DoubleDouble r_sum = fputil::exact_add(C1.hi, dx_c2.hi);
+ double r_hi = r_sum.hi;
+ double r_lo = r_sum.lo + dx_c2.lo;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ // Low parts polynomial evaluated in parallel:
+ // C1.lo + dx * (C2.lo + dx * C3.lo) + r_lo
+ double lo_tail = fputil::multiply_add(dx, C3.lo, C2.lo);
+ double lo_poly = fputil::multiply_add(dx, lo_tail, C1.lo + r_lo);
+
+ // Evaluate polynomial tail P(dx) using Estrin's scheme:
double dx2 = dx * dx;
- double c0 = fputil::multiply_add(dx, COEFFS[2], COEFFS[1]);
- double c1 = fputil::multiply_add(dx, COEFFS[4], COEFFS[3]);
- double c2 = fputil::multiply_add(dx, COEFFS[6], COEFFS[5]);
+ double c0 = fputil::multiply_add(dx, COEFFS[1], COEFFS[0]);
+ double c1 = fputil::multiply_add(dx, COEFFS[3], COEFFS[2]);
+ double c2 = fputil::multiply_add(dx, COEFFS[5], COEFFS[4]);
+
+ double dx4 = dx2 * dx2;
+ double d0 = fputil::multiply_add(dx2, c1, c0);
+ double p = fputil::multiply_add(dx4, c2, d0);
+
+ // High part of cubic term: C3.hi + dx * P(dx)
+ double q = fputil::multiply_add(dx, p, C3.hi);
- double p = fputil::polyeval(dx2, c0, c1, c2);
+ // Combine dx^2 * q into lo_poly:
+ lo_poly = fputil::multiply_add(dx2, q, lo_poly);
- // s = e_x - log2(r) + dx * P(dx)
- // Absolute error bound:
- // |log2(x) - log2_x.hi - log2_x.lo| < 2^-65.
+ // Multiply by dx to get log2(1 + dx) in DoubleDouble:
+ DoubleDouble log2_1p = fputil::exact_mult(dx, r_hi);
+ log2_1p.lo = fputil::multiply_add(dx, lo_poly, log2_1p.lo);
- // Notice that e_x - log2(r).hi is exact, so we perform an exact sum of
- // e_x - log2(r).hi and the high part of the product dx * c0:
- // log2_x_hi.hi + log2_x_hi.lo = e_x - log2(r).hi + (dx * c0).hi
+ // Combine with e_x - log2(r):
DoubleDouble log2_x_hi =
- fputil::exact_add(e_x + LOG2_R_DD[idx_x].hi, dx_c0.hi);
- // The low part is dx^2 * p + low part of (dx * c0) + low part of -log2(r).
- double log2_x_lo =
- fputil::multiply_add(dx2, p, dx_c0.lo + LOG2_R_DD[idx_x].lo);
- // Perform accurate sums.
+ fputil::exact_add(e_x + LOG2_R_DD[idx_x].hi, log2_1p.hi);
+ double log2_x_lo = log2_1p.lo + LOG2_R_DD[idx_x].lo;
DoubleDouble log2_x = fputil::exact_add(log2_x_hi.hi, log2_x_lo);
log2_x.lo += log2_x_hi.lo;
// To compute 2^(y * log2(x)), we break the exponent into 3 parts:
- // y * log(2) = hi + mid + lo, where
+ // y * log2(x) = hi + mid + lo, where
// hi is an integer
// mid * 2^6 is an integer
// |lo| <= 2^-7
@@ -451,96 +274,230 @@ LIBC_INLINE double pow(double x, double y) {
// and 2^lo ~ 1 + lo * P(lo).
// Thus, we have:
// hi + mid = 2^-6 * round( 2^6 * y * log2(x) )
- // If we restrict the output such that |hi| < 150, (hi + mid) uses (8 + 6)
+ // If we restrict the output such that |hi| < 512, (hi + mid) uses (9 + 6)
// bits, hence, if we use double precision to perform
// round( 2^6 * y * log2(x))
- // the lo part is bounded by 2^-7 + 2^(-(52 - 14)) = 2^-7 + 2^-38
+ // the lo part is bounded by 2^-7 + 2^(-(52 - 15)) = 2^-7 + 2^-37
// In the following computations:
// y6 = 2^6 * y
// hm = 2^6 * (hi + mid) = round(2^6 * y * log2(x)) ~ round(y6 * s)
// lo6 = 2^6 * lo = 2^6 * (y - (hi + mid)) = y6 * log2(x) - hm.
- double y6 = y * 0x1.0p6; // Exact.
+ constexpr double SCALE = 0x1.0p6;
+ double y6 = y * SCALE; // Exact.
DoubleDouble y6_log2_x = fputil::exact_mult(y6, log2_x.hi);
y6_log2_x.lo = fputil::multiply_add(y6, log2_x.lo, y6_log2_x.lo);
// Check overflow/underflow.
double scale = 1.0;
+ bool is_denorm = false;
// |2^(hi + mid) - exp2_hi_mid| <= ulp(exp2_hi_mid) / 2
- // Clamp the exponent part into smaller range that fits double precision.
- // For those exponents that are out of range, the final conversion will round
- // them correctly to inf/max float or 0/min float accordingly.
- constexpr double UPPER_EXP_BOUND = 512.0 * 0x1.0p6;
+
+ // The fast computation for 2^hi below requires that:
+ // |hi| < 512, or equivalently, |hm| < 512 * 2^6.
+ // This guarantees that the biased exponent:
+ // exp_biased = (hm_i >> 6) + EXP_BIAS = hi + 1023
+ // is strictly within the normal double range:
+ // 1023 - 511 <= exp_biased <= 1023 + 511, or 512 <= exp_biased <= 1534.
+ // Hence, 2^hi is always a normal, non-zero, finite power of 2, and the
+ // multiplication upper * exp2_hi is exact and never underflows or overflows.
+ //
+ // From the edge case checks above:
+ // 2^(-54) / 1074 <= |y| <= 1075 * 2^53, and
+ // |log_2(1 - 2^(-53))| <= |log2(x)| <= 1074.
+ // So their product is bounded by:
+ // 2^-117 < |y * log2(x)| < 2^74.
+ //
+ // The meaningful range for y * log2(x) in double precision is:
+ // -1075 <= y * log2(x) <= 1024.
+ // Any value > 1024 overflows, and any value < -1075 underflows.
+ //
+ // When |y * log2(x)| >= 511, we shift the exponent by an offset S:
+ // y * log2(x) = (y * log2(x) - S) + S
+ // and multiply by scale = 2^S at the end.
+ // To ensure the shifted exponent (y * log2(x) - S) stays within [-511, 511]:
+ // - For positive range [511, 1024]:
+ // 511 - S > -511 ==> S < 1022
+ // 1024 - S < 511 ==> S > 513
+ // - For negative range [-1076, -511]:
+ // -511 + S < 511 ==> S <= 1022
+ // -1076 + S > -511 ==> S >= 565
+ // Combined, the shift must satisfy: 565 <= S <= 1022.
+ // We choose S = 600, which yields:
+ // y * log2(x) - 600 in [-89, 424] for the positive range, and
+ // y * log2(x) + 600 in [-476, 89] for the negative range,
+ // both fitting well within [-511, 511].
+ //
+ // For exponents that are completely out of range:
+ // y * log2(x) > 1025 or y * log2(x) < -1076,
+ // the product can be as large as 2^74, so subtracting or adding 600 * 64
+ // would still overflow a 32-bit int when computing hm_i.
+ // We return early with overflow or underflow in these cases.
+ //
+ // Alternatively, for less branching or in SIMD / vector implementations, one
+ // could clamp y6_log2_x.hi to:
+ // - UPPER_EXP_BOUND (511 * 64) for overflow, which when multiplied by
+ // scale = 2^600 yields 2^1111 and correctly overflows.
+ // - -500 * 64 for underflow, which when multiplied by scale = 2^-600 yields
+ // 2^-1100 and correctly underflows.
+ // However, in this correctly rounded version, such clamping can cause the
+ // Ziv accuracy test to fail on the clamped exponent, unnecessarily
+ // triggering the slow accurate paths for overflow or underflow cases.
+
+ constexpr double UPPER_EXP_BOUND = 511.0 * SCALE;
if (LIBC_UNLIKELY(FPBits(y6_log2_x.hi).abs().get_val() >= UPPER_EXP_BOUND)) {
if (FPBits(y6_log2_x.hi).sign() == Sign::POS) {
- scale = 0x1.0p512;
- y6_log2_x.hi -= 512.0 * 64.0;
- if (y6_log2_x.hi > 513.0 * 64.0)
- y6_log2_x.hi = 513.0 * 64.0;
+ if (y6_log2_x.hi > 1025.0 * SCALE)
+ return set_overflow(is_neg);
+ scale = 0x1.0p600;
+ y6_log2_x.hi -= 600.0 * SCALE;
} else {
- scale = 0x1.0p-512;
- y6_log2_x.hi += 512.0 * 64.0;
- if (y6_log2_x.hi < (-1076.0 + 512.0) * 64.0)
- y6_log2_x.hi = -564.0 * 64.0;
+ if (y6_log2_x.hi <= -1021.0 * SCALE) {
+ if (y6_log2_x.hi < -1076.0 * SCALE)
+ return set_underflow(is_neg);
+ is_denorm = true;
+ } else {
+ scale = 0x1.0p-600;
+ y6_log2_x.hi += 600.0 * SCALE;
+ }
}
}
double hm = fputil::nearest_integer(y6_log2_x.hi);
// lo6 = 2^6 * lo.
- double lo6_hi = y6_log2_x.hi - hm;
- double lo6 = lo6_hi + y6_log2_x.lo;
+ DoubleDouble lo6 = fputil::exact_add(y6_log2_x.hi - hm, y6_log2_x.lo);
int hm_i = static_cast<int>(hm);
unsigned idx_y = static_cast<unsigned>(hm_i) & 0x3f;
// 2^hi
- int64_t exp2_hi_i = static_cast<int64_t>(
- static_cast<uint64_t>(static_cast<int64_t>(hm_i >> 6))
- << FPBits::FRACTION_LEN);
+ int hi = hm_i >> 6;
+ double exp2_hi = 1.0;
+ if (LIBC_LIKELY(!is_denorm)) {
+ int64_t exp2_hi_i = static_cast<int64_t>(
+ static_cast<uint64_t>(hi + FPBits::EXP_BIAS) << FPBits::FRACTION_LEN);
+ exp2_hi = FPBits(static_cast<uint64_t>(exp2_hi_i)).get_val();
+ }
+
// 2^mid
- int64_t exp2_mid_hi_i =
- static_cast<int64_t>(FPBits(EXP2_MID1[idx_y].hi).uintval());
- int64_t exp2_mid_lo_i =
- static_cast<int64_t>(FPBits(EXP2_MID1[idx_y].mid).uintval());
- // (-1)^sign * 2^hi * 2^mid
- // Error <= 2^hi * 2^-53
- uint64_t exp2_hm_hi_i =
- static_cast<uint64_t>(exp2_hi_i + exp2_mid_hi_i) + sign;
- // The low part could be 0.
- uint64_t exp2_hm_lo_i =
- idx_y != 0 ? static_cast<uint64_t>(exp2_hi_i + exp2_mid_lo_i) + sign
- : sign;
- double exp2_hm_hi = FPBits(exp2_hm_hi_i).get_val();
- double exp2_hm_lo = FPBits(exp2_hm_lo_i).get_val();
-
- // Degree-5 polynomial approximation P(lo6) ~ 2^(lo6 / 2^6) = 2^(lo).
- // Generated by Sollya with:
- // > P = fpminimax(2^(x/64), 5, [|1, D...|], [-2^-1, 2^-1]);
- // > dirtyinfnorm(2^(x/64) - P, [-0.5, 0.5]);
- // 0x1.a2b77e618f5c4c176fd11b7659016cde5de83cb72p-60
- constexpr double EXP2_COEFFS[] = {0x1p0,
- 0x1.62e42fefa39efp-7,
- 0x1.ebfbdff82a23ap-15,
- 0x1.c6b08d7076268p-23,
- 0x1.3b2ad33f8b48bp-31,
- 0x1.5d870c4d84445p-40};
-
- double lo6_sqr = lo6 * lo6;
-
- double d0 = fputil::multiply_add(lo6, EXP2_COEFFS[2], EXP2_COEFFS[1]);
- double d1 = fputil::multiply_add(lo6, EXP2_COEFFS[4], EXP2_COEFFS[3]);
- double pp = fputil::polyeval(lo6_sqr, d0, d1, EXP2_COEFFS[5]);
-
- double r = fputil::multiply_add(exp2_hm_hi * lo6, pp, exp2_hm_lo);
- r += exp2_hm_hi;
-
- return r * scale;
+ DoubleDouble exp2_mid{EXP2_MID1[idx_y].mid * sign_d,
+ EXP2_MID1[idx_y].hi * sign_d};
+
+ // Polynomial expansion for 2^(lo6/64):
+ // 2^(lo6/64) ~ 1 + lo6 * (log(2)/64) + lo6^2 * P(lo6)
+ // The linear term is computed in DoubleDouble, and the degree-3 polynomial
+ // P(lo6) is evaluated with standard double precision.
+ //
+ // hi and lo parts of log(2)/64, generated by Sollya with:
+ // > a = D(log(2)/64);
+ // > b = D(log(2)/64 - a);
+ constexpr DoubleDouble LOG_2_OVER_64 = {0x1.abc9e3b39803fp-62,
+ 0x1.62e42fefa39efp-7};
+
+ // Degree-3 polynomial approximation for (2^(lo6/64) - 1 - lo6*log(2)/64) /
+ // lo6^2: Generated by Sollya with:
+ // > f = (2^(x/64) - 1 - x*log(2)/64) / x^2;
+ // > P = fpminimax(f, 5, [|D...|], [-0.5, 0.5]);
+ // > dirtyinfnorm((f - P) * x^2, [-0.5, 0.5]);
+ // 0x1.1778...p-73
+ constexpr double EXP2_COEFFS[] = {
+ 0x1.ebfbdff82c58fp-15, 0x1.c6b08d704a0cp-23, 0x1.3b2ab6fb4d08fp-31,
+ 0x1.5d87fe77a735dp-40, 0x1.430d835610044p-49, 0x1.ffe67c38112c3p-59};
+
+ DoubleDouble lo_log_2 = fputil::quick_mult(lo6, LOG_2_OVER_64);
+ DoubleDouble lo_log_2_p1 = fputil::exact_add(1.0, lo_log_2.hi);
+ lo_log_2_p1.lo += lo_log_2.lo;
+
+ double lo6_sq = lo6.hi * lo6.hi;
+ double e0 = fputil::multiply_add(lo6.hi, EXP2_COEFFS[1], EXP2_COEFFS[0]);
+ double e1 = fputil::multiply_add(lo6.hi, EXP2_COEFFS[3], EXP2_COEFFS[2]);
+ double e2 = fputil::multiply_add(lo6.hi, EXP2_COEFFS[5], EXP2_COEFFS[4]);
+
+ double lo6_4 = lo6_sq * lo6_sq;
+ double f0 = fputil::multiply_add(lo6_sq, e0, lo_log_2_p1.lo);
+ double f1 = fputil::multiply_add(lo6_sq, e2, e1);
+
+ lo_log_2_p1.lo = fputil::multiply_add(lo6_4, f1, f0);
+ DoubleDouble r = fputil::quick_mult(exp2_mid, lo_log_2_p1);
+
+ // Absolute error bound for r:
+ // - Base error from exp2 stage is bounded by 0x1.0p-64.
+ // - Propagated error from log2(x):
+ // |y| * err(log2(x)) * (2^mid * log(2)) <= |y| * 2^-73.5
+ // Dynamic error bound adapting to exponent scale |y|:
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double err_r =
+ fputil::multiply_add(FPBits(y).abs().get_val(), 0x1.8p-73, 0x1.0p-64);
+#else // !LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ // Without FMA, intermediate roundings increase log2(x) and exp2 errors.
+ double err_r =
+ fputil::multiply_add(FPBits(y).abs().get_val(), 0x1.cp-72, 0x1.0p-63);
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ if (LIBC_UNLIKELY(is_denorm)) {
+ if (auto r_denorm = ziv_test_denorm(hi, r.hi, r.lo, err_r, is_neg);
+ LIBC_LIKELY(r_denorm.has_value())) {
+ double res = r_denorm.value();
+
+ // Since is_denorm is triggered when y * log2(x) <= -1021 * 2^6, the
+ // rounded result can still be a normal number (>= 2^-1022). In that
+ // case, no underflow has occurred, so return directly.
+ if (LIBC_UNLIKELY(FPBits(res).is_normal()))
+ return res;
+
+ // When the rounded result is denormal or zero, underflow and ERANGE
+ // should only be set if the result is inexact. We check for exact
+ // results:
+ // 1. If x = 2^e_x (x_mant == 0), then x^y = 2^(e_x * y) is an exact
+ // power of 2 iff e_x * y is an integer and >= -1074.0 (the smallest
+ // representable power of 2 in double precision).
+ if (LIBC_UNLIKELY(x_mant == 0)) {
+ double ex_y = e_x * y;
+ if (ex_y >= -1074.0 && pow_internal::is_integer(ex_y))
+ return res;
+ } else if (LIBC_UNLIKELY(y > 0.0 && y <= 35.0)) {
+ // 2. If x is not a power of 2, exact results in double precision can
+ // only occur for 0 < y <= 35 (Lauter and Lefevre). If it falls on
+ // an exact boundary, convert via DyadicFloat to ensure that
+ // underflow and inexact exceptions are not signaled.
+ uint64_t exact_m = 0;
+ int exact_exp = 0;
+ if (pow_internal::is_exact_rounding_boundary(x, y, exact_m,
+ exact_exp)) {
+ int l = 64 - cpp::countl_zero(exact_m);
+ pow_internal::DFloat128 exact_f128(
+ is_neg ? Sign::NEG : Sign::POS, exact_exp + l - 128,
+ pow_internal::MantissaType(exact_m) << (128 - l));
+ exact_f128.normalize();
+ return static_cast<double>(exact_f128);
+ }
+ }
+
+ // Otherwise, the denormal or zero result is inexact, so we signal the
+ // underflow exception and set ERANGE if required.
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+ return res;
+ }
+ return pow_accurate(x, y, is_neg, static_cast<int>(e_x), idx_x, dx);
+ }
+
+ double upper = r.hi + (r.lo + err_r);
+ double lower = r.hi + (r.lo - err_r);
+ if (LIBC_LIKELY(upper == lower)) {
+ double tmp1 = upper * exp2_hi;
+ return tmp1 * scale;
+ }
+
+ return pow_accurate(x, y, is_neg, static_cast<int>(e_x), idx_x, dx);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_POW_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_128.h
new file mode 100644
index 00000000000..36d03e3c09e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_128.h
@@ -0,0 +1,375 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// 128-bit accurate path for double-precision pow(x, y).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_128_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_128_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/frac128.h"
+#include "src/__support/frac64.h"
+#include "src/__support/integer_literals.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/common_constants.h"
+#include "src/__support/math/pow_accurate_256.h"
+#include "src/__support/math/pow_utils.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace pow_internal {
+
+using DFloat128 = typename fputil::DyadicFloat<128>;
+using MantissaType = typename DFloat128::MantissaType;
+using LIBC_NAMESPACE::operator""_u128;
+
+// exp2_f128 shares EXP2_MID_FRAC256 from pow_accurate_256.h via
+// Frac256::to_frac128().
+
+// Polynomial approximation for log2(1 + dx):
+// For dx in [-2^-8, 2^-7], we approximate:
+// P(x) ~ log2(1 + x) / (2 * x)
+// then:
+// log2(1 + dx) = 2 * dx * P(dx).
+//
+// Minimax polynomial coefficients generated by Sollya with:
+// > prec = 256;
+// > P = fpminimax(log2(1 + x) / (2 * x), 15, [|127...|], [-2^(-8), 2^(-7)],
+// fixed);
+// > for i from 0 to 15 do {
+// c = coeff(P, i);
+// c_int = round(abs(c) * 2^127, 256, RN);
+// lo = c_int mod 2^64;
+// hi = (c_int - lo) / 2^64;
+// print("Frac128({", lo, "ULL,", hi, "ULL}), // a_", i);
+// };
+// > dirtyinfnorm(log2(1 + x) - 2 * x * P, [-2^(-8), 2^(-7)]);
+// 0x1.c6524...p-139 < 2^-138.
+//
+// Expanding P(x) in Horner form:
+// P(x) = a_0 - a_1 * x + a_2 * x^2 - a_3 * x^3 + ...
+// We store the absolute values of the coefficients |a_k| as Frac128.
+//
+// With y = |dx|,
+// - if dx >= 0:
+// P(y) = |a_0| - y * (|a_1| - y * (|a_2| - ...))
+// - if dx < 0:
+// P(-y) = |a_0| + y * (|a_1| + y * (|a_2| + ...))
+LIBC_INLINE_VAR constexpr Frac128 LOG2_POLY_128[16] = {
+ Frac128({0xdf43ff68348e9f44ULL, 0x5c551d94ae0bf85dULL}), // a_0
+ Frac128({0xefa1ffb41a474fa2ULL, 0x2e2a8eca5705fc2eULL}), // a_1
+ Frac128({0x9fc15522bc34caf6ULL, 0x1ec709dc3a03fd74ULL}), // a_2
+ Frac128({0x77d0ffda0d2838eaULL, 0x171547652b82fe17ULL}), // a_3
+ Frac128({0x2ca733033277ada0ULL, 0x12776c50ef9bfe79ULL}), // a_4
+ Frac128({0x4fe0aa8003f351fbULL, 0x0f6384ee1d01febaULL}), // a_5
+ Frac128({0xb2490fe2b526029dULL, 0x0d30bb153d6f6c9fULL}), // a_6
+ Frac128({0xbc03c43080705d70ULL, 0x0b8aa3b295c17f0bULL}), // a_7
+ Frac128({0x8db7017adcd9fd4dULL, 0x0a42589ebe015466ULL}), // a_8
+ Frac128({0x7a1820b5f15e8892ULL, 0x093bb62877cdff26ULL}), // a_9
+ Frac128({0xfb43ea327ddb209cULL, 0x0864d424ca0b0f9dULL}), // a_10
+ Frac128({0xca32556a02086730ULL, 0x07b1c2770e8b0fabULL}), // a_11
+ Frac128({0xb05fb6d59979dddeULL, 0x071a3d579502ad57ULL}), // a_12
+ Frac128({0x4abbb99c78464ef1ULL, 0x06985d880590b72bULL}), // a_13
+ Frac128({0x86477a0bb2fb6379ULL, 0x06282cce144a837eULL}), // a_14
+ Frac128({0x25363223e4195930ULL, 0x05c5acde28e4f0bfULL}), // a_15
+};
+
+// Accurate log2(x) in 128-bit precision reusing range reduction from fast pass:
+// x = 2^x_e * m_x, with 1 <= m_x < 2
+// r = RD[idx_x]
+// dx = r * m_x - 1, with -2^-8 <= dx < 2^-7
+// log2(x) = x_e + (-log2(r)) + log2(1 + dx).
+// The value -log2(r) is provided by LOG2_RD_FRAC256[idx_x].
+// log2(1 + dx) is evaluated with a degree-15 minimax polynomial using a 2-tier
+// Horner scheme (Frac64 and Frac128).
+LIBC_INLINE DFloat128 log2_f128(int x_e, unsigned idx_x, double dx) {
+ using FPBits = fputil::FPBits<double>;
+
+ if (dx == 0.0) {
+ Frac128 log2_m = LOG2_RD_FRAC256[idx_x].to_frac128();
+ DFloat128 m_df(Sign::POS, -127, log2_m);
+ return fputil::quick_add(DFloat128(static_cast<double>(x_e)), m_df);
+ }
+
+ double abs_dx = (dx < 0.0) ? -dx : dx;
+ FPBits bits(abs_dx);
+ // Append hidden bit.
+ uint64_t mant = bits.get_mantissa() | (1ULL << 52);
+ int shift = 127 + bits.get_exponent() - 52;
+ Frac128 y =
+ (shift >= 0) ? Frac128((UInt<128>(mant) << shift).val) : Frac128(0);
+
+ // Evaluate log2(1 + dx) using Horner scheme in 2 stages:
+ // - Degree 8-15: 64-bit precision evaluation.
+ // - Degree 0-7: 128-bit precision evaluation.
+ //
+ // Since y = |dx| <= 2^-7, truncation errors at degree k is bounded by:
+ // y^k <= 2^(-7k).
+ //
+ // Step 1: 64-bit evaluation, with truncation error at degree 8 is bounded by:
+ // 2^-63 * y^8 <= 2^-119.
+ Frac64 y64 = y.to_frac64();
+ Frac64 p64 = LOG2_POLY_128[15].to_frac64();
+ if (dx >= 0.0) {
+ for (int k = 14; k >= 8; --k)
+ p64 = LOG2_POLY_128[k].to_frac64() - ((p64 * y64) << 1);
+ } else {
+ for (int k = 14; k >= 8; --k)
+ p64 = LOG2_POLY_128[k].to_frac64() + ((p64 * y64) << 1);
+ }
+
+ // Step 2: 128-bit evaluation.
+ Frac128 p({0, p64.val[0]});
+ if (dx >= 0.0) {
+ for (int k = 7; k >= 0; --k)
+ p = LOG2_POLY_128[k] - ((p * y) << 1);
+ } else {
+ for (int k = 7; k >= 0; --k)
+ p = LOG2_POLY_128[k] + ((p * y) << 1);
+ }
+
+ // log2(1 + dx) = 2 * y * P(y):
+ Frac128 log2_1p = (y * p) << 2;
+ Frac128 log2_rd = LOG2_RD_FRAC256[idx_x].to_frac128();
+ Frac128 log2_m = (dx >= 0.0) ? (log2_rd + log2_1p) : (log2_rd - log2_1p);
+
+ DFloat128 m_df(Sign::POS, -127, log2_m);
+ return fputil::quick_add(DFloat128(static_cast<double>(x_e)), m_df);
+}
+
+// Polynomial approximation for (2^x - 1) / x:
+// For x in [-2^-8, 2^-7], we approximate:
+// P(x) ~ (2^x - 1) / x
+// then:
+// 2^x = 1 + x * P(x).
+//
+// Minimax polynomial coefficients generated by Sollya with:
+// > prec = 500;
+// > P = fpminimax((2^x - 1)/x, 11, [|127...|], [-2^(-8), 2^(-7)], fixed);
+// > for i from 0 to 11 do {
+// c = coeff(P, i);
+// c_int = round(abs(c) * 2^127, 256, RN);
+// lo = c_int mod 2^64;
+// hi = (c_int - lo) / 2^64;
+// print("Frac128({", lo, "ULL,", hi, "ULL}), // c_", i);
+// };
+// > dirtyinfnorm(2^x - (1 + x * P), [-2^(-8), 2^(-7)]);
+// 0x1.4c648...p-139 < 2^-138.
+//
+// Expanding P(x) in Horner form:
+// P(x) = c_0 + c_1 * x + c_2 * x^2 + ...
+// where c_k ~ (log(2))^(k+1) / (k+1)! are all positive.
+//
+// With u = |x|,
+// - if x >= 0:
+// P(u) = c_0 + u * (c_1 + u * (c_2 + ...))
+// - if x < 0:
+// P(-u) = c_0 - u * (c_1 - u * (c_2 - ...))
+LIBC_INLINE_VAR constexpr Frac128 EXP2_POLY_128[12] = {
+ Frac128({0xe4f1d9cc01f97b58ULL, 0x58b90bfbe8e7bcd5ULL}), // c_0
+ Frac128({0x6f16b06ec9735fcbULL, 0x1ebfbdff82c58ea8ULL}), // c_1
+ Frac128({0xcce9d8aeccad816eULL, 0x071ac235c1282fe2ULL}), // c_2
+ Frac128({0x9ccbbe0b53ecfa40ULL, 0x013b2ab6fba4e772ULL}), // c_3
+ Frac128({0x20e2fed5a256d4e6ULL, 0x002bb0ffcf14ce62ULL}), // c_4
+ Frac128({0xdbd2c2a4af40b4b6ULL, 0x00050c244be1b1e1ULL}), // c_5
+ Frac128({0x1a199575c57ddfaaULL, 0x00007ff2ff1622c3ULL}), // c_6
+ Frac128({0x11fd7e22defbeaf5ULL, 0x00000b160111d2e4ULL}), // c_7
+ Frac128({0x7681395eb574dbfbULL, 0x000000da929e9cafULL}), // c_8
+ Frac128({0x1814285a9da99308ULL, 0x0000000f267a8ac6ULL}), // c_9
+ Frac128({0xafddba4f901557d4ULL, 0x00000000f46563d0ULL}), // c_10
+ Frac128({0x7ae715abc468c5f0ULL, 0x000000000e1de423ULL}), // c_11
+};
+
+// Compute 2^z in 128-bit precision:
+// Range reduction:
+// k = round(z * 64)
+// hi = k >> 6
+// idx = k & 0x3f
+// lo = z - k * 2^-6, with |lo| <= 2^-7.
+// Then:
+// 2^z = 2^hi * EXP2_MID_FRAC256[idx] * 2^lo
+// = 2^hi * EXP2_MID_FRAC256[idx] * (1 + lo * P(lo)).
+LIBC_INLINE DFloat128 exp2_f128(const DFloat128 &z) {
+ double z_d = static_cast<double>(z);
+ double z_scaled = z_d * 64.0;
+ double kd = fputil::nearest_integer(z_scaled);
+ int k = static_cast<int>(kd);
+
+ int hi = k >> 6;
+ unsigned idx = static_cast<unsigned>(k & 0x3f);
+
+ DFloat128 kd_f128(kd * 0x1.0p-6);
+ DFloat128 lo = fputil::quick_add(z, -kd_f128);
+
+ Frac128 m = EXP2_MID_FRAC256[idx].to_frac128();
+ if (LIBC_UNLIKELY(lo.mantissa.is_zero()))
+ return DFloat128(Sign::POS, hi - 127, m);
+
+ bool lo_is_neg = (lo.sign == Sign::NEG);
+ int shift = -127 - lo.exponent;
+ Frac128 u = (shift < 128) ? Frac128((lo.mantissa >> shift).val) : Frac128(0);
+
+ // Evaluate 2^lo - 1 = lo * P(lo) using Horner scheme in 2 stages:
+ // - Degree 7-11: 64-bit precision evaluation.
+ // - Degree 0-6: 128-bit precision evaluation.
+ //
+ // Since u = |lo| <= 2^-7, truncation errors at degree i is bounded by:
+ // u^i <= 2^(-7i).
+ //
+ // Step 1: 64-bit evaluation, with truncation error at degree 7 is bounded by:
+ // 2^-63 * u^7 <= 2^-112.
+ Frac64 u64 = u.to_frac64();
+ Frac64 p64 = EXP2_POLY_128[11].to_frac64();
+ if (lo_is_neg) {
+ for (int i = 10; i >= 7; --i)
+ p64 = EXP2_POLY_128[i].to_frac64() - ((p64 * u64) << 1);
+ } else {
+ for (int i = 10; i >= 7; --i)
+ p64 = EXP2_POLY_128[i].to_frac64() + ((p64 * u64) << 1);
+ }
+
+ // Step 2: 128-bit evaluation.
+ Frac128 p({0, p64.val[0]});
+ if (lo_is_neg) {
+ for (int i = 6; i >= 0; --i)
+ p = EXP2_POLY_128[i] - ((p * u) << 1);
+ } else {
+ for (int i = 6; i >= 0; --i)
+ p = EXP2_POLY_128[i] + ((p * u) << 1);
+ }
+
+ // Reconstruction:
+ // t = u * P(u) ~ 2^u - 1 as Frac128
+ // mt = m * t ~ m * (2^u - 1) as Frac128
+ // m_final = m +- mt ~ m * (1 +- t) ~ m * 2^lo
+ Frac128 t = (u * p) << 1;
+ Frac128 mt = (m * t) << 1;
+ Frac128 m_final = lo_is_neg ? (m - mt) : (m + mt);
+
+ if ((m_final.val[1] & (1ULL << 63)) == 0) {
+ m_final = m_final << 1;
+ --hi;
+ }
+
+ return DFloat128(Sign::POS, hi - 127, m_final);
+}
+
+// Accurate pow(x, y) reusing range reduction parameters from the fast pass.
+LIBC_INLINE double pow_accurate(double x, double y, bool is_neg, int x_e,
+ unsigned idx_x, double dx) {
+ DFloat128 log2_x = log2_f128(x_e, idx_x, dx);
+ DFloat128 y_f128(y);
+ DFloat128 z = fputil::quick_mul(y_f128, log2_x);
+
+ // 2^1025 > max normal double.
+ double z_d = static_cast<double>(z);
+ if (LIBC_UNLIKELY(z_d >= 1025.0))
+ return set_overflow(is_neg);
+
+ // 2^-1076 < min subnormal double.
+ if (LIBC_UNLIKELY(z_d <= -1076.0))
+ return set_underflow(is_neg);
+
+ // For 0 < |z| <= 2^-55, x^y is between 1 - 2^-54 and 1 + 2^-53.
+ if (LIBC_UNLIKELY(!z.mantissa.is_zero() && z.exponent + 127 <= -55)) {
+ volatile double one = 1.0;
+ volatile double eps = (z.sign == Sign::NEG) ? -0x1.0p-100 : 0x1.0p-100;
+ double res = one + eps;
+ return is_neg ? -res : res;
+ }
+
+ DFloat128 r = exp2_f128(z);
+ if (is_neg)
+ r.sign = Sign::NEG;
+
+ int unbiased_exp = r.exponent + 127;
+ if (LIBC_UNLIKELY(unbiased_exp >= 1024))
+ return set_overflow(is_neg);
+
+ // Check if r is close to a 54-bit rounding boundary (either an exact 53-bit
+ // float or a midpoint).
+ // For normal numbers, the 54 leading bits occupy bits [127:74] of r.mantissa,
+ // leaving shift = 128 - 54 = 74 fractional bits below the boundary.
+ // For subnormal numbers (unbiased_exp < -1022), the boundary shifts right.
+ int shift = 74;
+ if (LIBC_UNLIKELY(unbiased_exp < -1022))
+ shift = 74 - (-1022 - unbiased_exp);
+
+ bool is_boundary_candidate = false;
+ // Lauter & Lefevre (2009) showed that if x^y is not an exact 54-bit number,
+ // the distance to the nearest 54-bit boundary is at least:
+ // |x^y - o_54(x^y)| / x^y >= 2^-114.
+ // In r.mantissa, this minimum distance is 2^-114 * 2^127 = 2^13.
+ //
+ // Since eps_bound >= 2^13, when shift < 14, the maximum possible distance to
+ // the nearest boundary, 2^(shift - 1) <= 2^12, is strictly less than
+ // eps_bound, making every value a candidate. Checking shift >= 14 also
+ // prevents undefined negative shifts for denormals.
+ if (shift >= 14) {
+ // Distance from r.mantissa to the nearest multiple of 2^shift:
+ MantissaType mask = (MantissaType(1) << shift) - 1;
+ MantissaType rem = r.mantissa & mask;
+ MantissaType half = MantissaType(1) << (shift - 1);
+ MantissaType dist =
+ (rem <= half) ? rem : ((MantissaType(1) << shift) - rem);
+
+ // Evaluation error in r.mantissa is bounded by:
+ // log(2) * |y| * AbsErr(log2_x) * 2^127 + AbsErr(exp2_z)
+ // <= log(2) * 32 * |y| + 2^13
+ // < 32 * |y| + 2^13.
+ // For |y| >= 2^59, 32 * |y| >= 2^64, so we cap eps_bound at 2^64 to avoid
+ // 64-bit integer overflow.
+ double abs_y = (y < 0.0) ? -y : y;
+ MantissaType eps_bound = MantissaType(1) << 13;
+ if (LIBC_LIKELY(abs_y < 0x1.0p59))
+ eps_bound += (MantissaType(static_cast<uint64_t>(abs_y)) << 5);
+ else
+ eps_bound = (MantissaType(1) << 64);
+ is_boundary_candidate = (dist < eps_bound);
+ } else {
+ is_boundary_candidate = true;
+ }
+
+ if (LIBC_UNLIKELY(is_boundary_candidate)) {
+ uint64_t exact_m = 0;
+ int exact_exp = 0;
+ if (is_exact_rounding_boundary(x, y, exact_m, exact_exp)) {
+ int l = 64 - cpp::countl_zero(exact_m);
+ DFloat128 exact_f128(r.sign, exact_exp + l - 128,
+ MantissaType(exact_m) << (128 - l));
+ exact_f128.normalize();
+
+ return static_cast<double>(exact_f128);
+ }
+
+ return pow_accurate_256(y, is_neg, x_e, idx_x, dx);
+ }
+
+ double res = static_cast<double>(r);
+ if (LIBC_UNLIKELY(fputil::FPBits<double>(res).is_inf()))
+ return set_overflow(is_neg);
+ return res;
+}
+
+} // namespace pow_internal
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_256.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_256.h
new file mode 100644
index 00000000000..bb2deae4c4f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_accurate_256.h
@@ -0,0 +1,818 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// 256-bit accurate path for double-precision pow(x, y).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_256_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_256_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/frac256.h"
+#include "src/__support/frac64.h"
+#include "src/__support/integer_literals.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/pow_utils.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace pow_internal {
+
+using DFloat256 = typename fputil::DyadicFloat<256>;
+using Mantissa256 = typename DFloat256::MantissaType;
+
+// Polynomial approximation for log2(1 + dx):
+// For dx in [-2^-8, 2^-7], we approximate:
+// P(x) ~ log2(1 + x) / (2 * x)
+// then:
+// log2(1 + dx) = 2 * dx * P(dx).
+//
+// Minimax polynomial coefficients generated by Sollya with:
+// > prec = 512;
+// > P = fpminimax(log2(1 + x) / (2 * x), 30, [|255...|], [-2^(-8), 2^(-7)],
+// fixed);
+// > for i from 0 to 30 do {
+// c = coeff(P, i);
+// c_int = round(abs(c) * 2^255, 512, RN);
+// print(c_int);
+// };
+// > dirtyinfnorm(log2(1 + x) - 2 * x * P, [-2^(-8), 2^(-7)]);
+// 0x1.bb204...p-270 < 2^-266.
+//
+// Expanding P(x) in Horner form:
+// P(x) = a_0 - a_1 * x + a_2 * x^2 - a_3 * x^3 + ...
+// We store the absolute values of the coefficients |a_k| as Frac256.
+//
+// With y = |dx|,
+// - if dx >= 0:
+// P(y) = |a_0| - y * (|a_1| - y * (|a_2| - ...))
+// - if dx < 0:
+// P(-y) = |a_0| + y * (|a_1| + y * (|a_2| + ...))
+LIBC_INLINE_VAR constexpr Frac256 LOG2_POLY_256[31] = {
+ Frac256({0x45928b3668d09924ULL, 0x75abbd546eb4ad2cULL,
+ 0xdf43ff68348e9f44ULL, 0x5c551d94ae0bf85dULL}), // a_0
+ Frac256({0x22c9459b34684c8aULL, 0x3ad5deaa375a5696ULL,
+ 0xefa1ffb41a474fa2ULL, 0x2e2a8eca5705fc2eULL}), // a_1
+ Frac256({0x1730d91222eb39a3ULL, 0x27393f1c24e6e464ULL,
+ 0x9fc15522bc2f8a6cULL, 0x1ec709dc3a03fd74ULL}), // a_2
+ Frac256({0x1164a2cd9b640d52ULL, 0x1d6aef551bad2b4bULL,
+ 0x77d0ffda0d23a7d1ULL, 0x171547652b82fe17ULL}), // a_3
+ Frac256({0xa783b5e0b932720eULL, 0x1788bf77495755d5ULL,
+ 0x2ca73314d74fb974ULL, 0x12776c50ef9bfe79ULL}), // a_4
+ Frac256({0x0b986b9531f9d509ULL, 0x139c9f8e12737232ULL,
+ 0x4fe0aa915e17c536ULL, 0x0f6384ee1d01febaULL}), // a_5
+ Frac256({0x97a9d262490024e5ULL, 0x10cf6430a219cf98ULL,
+ 0xb22e490ee2efcd9cULL, 0x0d30bb153d6f6c9fULL}), // a_6
+ Frac256({0x8a48b0b4c37bacd5ULL, 0x8eb577aa8dd695a4ULL,
+ 0xbbe87fed0691d3e8ULL, 0x0b8aa3b295c17f0bULL}), // a_7
+ Frac256({0xb0583590fcb47a20ULL, 0x62686a5eb6f7bc5bULL,
+ 0x354071b63eba8379ULL, 0x0a42589ebe01547cULL}), // a_8
+ Frac256({0xed3f5ebc7c98a745ULL, 0x0bc45fbba4b78402ULL,
+ 0x9653998a6ba7dcbaULL, 0x093bb62877cdff3cULL}), // a_9
+ Frac256({0x7359984444b13a62ULL, 0x96556e4d1cd07a22ULL,
+ 0x2b91d166906a0e7aULL, 0x0864d424ca011694ULL}), // a_10
+ Frac256({0x33fa41c7bb5906d1ULL, 0x09ce4f8602a57acbULL,
+ 0x27f05548af0be29bULL, 0x07b1c2770e80ff5dULL}), // a_11
+ Frac256({0x3cd309be8234c315ULL, 0xf55cdd54ec97ae7fULL,
+ 0x388f13a58de39618ULL, 0x071a3d5a34c5d807ULL}), // a_12
+ Frac256({0xa481c98db0b1aff6ULL, 0x093722cc884edbbfULL,
+ 0xd91724877177e6ceULL, 0x06985d8a9eb7b64fULL}), // a_13
+ Frac256({0xc5ebfbd7f8f11467ULL, 0xba98bfd7dd3b3734ULL,
+ 0xb98d1106f26fe87aULL, 0x0627cec5a533ff7dULL}), // a_14
+ Frac256({0x8f5b01e8d6775018ULL, 0x761efcd442a1522bULL,
+ 0xddf43ff68348e853ULL, 0x05c551d94ae0bf85ULL}), // a_15
+ Frac256({0xaa2b7924b8634b56ULL, 0x0bb2cd446fa9eca9ULL,
+ 0xd0e5e1d8f4097fddULL, 0x056e6b26dd0fc350ULL}), // a_16
+ Frac256({0x5a3861ff74fe9726ULL, 0x67655566edd6ee5dULL,
+ 0x1aa038db217aa2f2ULL, 0x05212c4f5f00aa3eULL}), // a_17
+ Frac256({0x8e5b3868f6fd9a2bULL, 0x86ad9ad6b3808b9dULL,
+ 0x26b2bc9961df0451ULL, 0x04dc0f07d343ff99ULL}), // a_18
+ Frac256({0xd5aff98461aaaa10ULL, 0x6d86f9b7f2a0e47bULL,
+ 0x4b29cb04bafb62c9ULL, 0x049ddb143be6ff9eULL}), // a_19
+ Frac256({0x73e005b24f0b5921ULL, 0x79754c39f3650d18ULL,
+ 0x3b6462eeb984c6bfULL, 0x046593b1bf252435ULL}), // a_20
+ Frac256({0xbfe649c5ee1a2476ULL, 0xa979d5e9dd8792fcULL,
+ 0x16a5af95b3d52886ULL, 0x04326a1265008b4aULL}), // a_21
+ Frac256({0xb240c3c658e84513ULL, 0x5a0dc3a6d6dcfbcbULL,
+ 0x3250ee4b9aa7a10cULL, 0x0403b35f8200853cULL}), // a_22
+ Frac256({0xa79c9e1b001812d1ULL, 0xc371e02ecf7b2649ULL,
+ 0xbc02b8b45c8cbd91ULL, 0x03d8e13b87407f7cULL}), // a_23
+ Frac256({0x396cbdb266e04da2ULL, 0xf42521f706b70fb3ULL,
+ 0xc4949cec1b5b8eb0ULL, 0x03b17c102febc7f2ULL}), // a_24
+ Frac256({0x623e4d738fe3f137ULL, 0x6d666a8379a8770dULL,
+ 0xddbb37796ef31775ULL, 0x038d1ead1a5f0977ULL}), // a_25
+ Frac256({0x90aab3e1d0b7c642ULL, 0x65353252593e6d5bULL,
+ 0x0a50523f5de27e92ULL, 0x036b72dfa00d56f3ULL}), // a_26
+ Frac256({0x57b2859b2032fbedULL, 0xe13ac78494bc3804ULL,
+ 0xc717595704ee1587ULL, 0x034c2ec97b40b274ULL}), // a_27
+ Frac256({0xaacab0e905a586e3ULL, 0x4c5437b1d3769115ULL,
+ 0x3db148838720c9e9ULL, 0x032f124ccfb211fcULL}), // a_28
+ Frac256({0xb0f6f05d9338d95fULL, 0x43c399e43c54795fULL,
+ 0x44b5111834acb3d6ULL, 0x031357dab283c21cULL}), // a_29
+ Frac256({0x676b154931b3d988ULL, 0x8e0bff4ea0623d39ULL,
+ 0xe8a2fa21caed0f90ULL, 0x02d819fe5a43f238ULL}), // a_30
+};
+
+// Polynomial approximation for (2^x - 1) / x:
+// For x in [-2^-8, 2^-7], we approximate:
+// P(x) ~ (2^x - 1) / x
+// then:
+// 2^x = 1 + x * P(x).
+//
+// Minimax polynomial coefficients generated by Sollya with:
+// > prec = 512;
+// > P = fpminimax((2^x - 1) / x, 21, [|255...|], [-2^(-8), 2^(-7)], fixed);
+// > for i from 0 to 21 do {
+// c = coeff(P, i);
+// c_int = round(abs(c) * 2^255, 512, RN);
+// print(c_int);
+// };
+// > dirtyinfnorm(2^x - (1 + x * P), [-2^(-8), 2^(-7)]);
+// 0x1.1554a...p-269 < 2^-268.
+//
+// Expanding P(x) in Horner form:
+// P(x) = c_0 + c_1 * x + c_2 * x^2 + ...
+// where c_k ~ (log(2))^(k+1) / (k+1)! are all positive.
+//
+// With u = |x|,
+// - if x >= 0:
+// P(u) = c_0 + u * (c_1 + u * (c_2 + ...))
+// - if x < 0:
+// P(-u) = c_0 - u * (c_1 - u * (c_2 - ...))
+LIBC_INLINE_VAR constexpr Frac256 EXP2_POLY_256[22] = {
+ Frac256({0xc5068badc5d57d16ULL, 0xa079a193394c5b16ULL,
+ 0xe4f1d9cc01f97b57ULL, 0x58b90bfbe8e7bcd5ULL}), // c_0
+ Frac256({0xc2be93bbb1396e6eULL, 0xa3a2751c30ce69d4ULL,
+ 0x6f16b06ec9735fcaULL, 0x1ebfbdff82c58ea8ULL}), // c_1
+ Frac256({0x4753198ade221489ULL, 0xa7ae23a226d00887ULL,
+ 0xcce9d8aeccaf4b7bULL, 0x071ac235c1282fe2ULL}), // c_2
+ Frac256({0x699b709699e59d1cULL, 0x72478ea53e63911dULL,
+ 0x9ccbbe0b53eeac50ULL, 0x013b2ab6fba4e772ULL}), // c_3
+ Frac256({0xc8cdc3747ffed019ULL, 0x60aed94d2dce32e1ULL,
+ 0x20e2fed34a297d86ULL, 0x002bb0ffcf14ce62ULL}), // c_4
+ Frac256({0x549592ed6dd93585ULL, 0xcfb314ffccc47bb0ULL,
+ 0xdbd2c2a261ac8d07ULL, 0x00050c244be1b1e1ULL}), // c_5
+ Frac256({0x5d0fe48ff2c6f3f5ULL, 0x4ace1152e8810feeULL,
+ 0x1a1ac547321f639aULL, 0x00007ff2ff1622c3ULL}), // c_6
+ Frac256({0x7d81cc760a6cb8d0ULL, 0x2586e1a0f7107ab9ULL,
+ 0x11fec7ff3036d3beULL, 0x00000b160111d2e4ULL}), // c_7
+ Frac256({0x08c1c3fcab2a43d5ULL, 0x84518cb8caa9ba63ULL,
+ 0x3e1ed253872d27fcULL, 0x000000da929e9cafULL}), // c_8
+ Frac256({0x4cefc19f553e7564ULL, 0xb4ce2a0608a16541ULL,
+ 0xc764fb7ed0eca973ULL, 0x0000000f267a8ac5ULL}), // c_9
+ Frac256({0x561e9aeb9041ed25ULL, 0x90a4edc7b3b041c3ULL,
+ 0x8dd92607abccaf23ULL, 0x00000000f465639aULL}), // c_10
+ Frac256({0x277d61ed12e707bcULL, 0xd17730e76ad24fc6ULL,
+ 0x7e14c2f15ab43f0bULL, 0x000000000e1deb28ULL}), // c_11
+ Frac256({0xd72a83926cf51bcaULL, 0x7b8d8d1512799500ULL,
+ 0x8b3687cb140d6180ULL, 0x0000000000c0b0c9ULL}), // c_12
+ Frac256({0xd3a3f9891ddac9deULL, 0x2ae5760179b7f299ULL,
+ 0x26ac3c54b9f8a1b1ULL, 0x0000000000098a4bULL}), // c_13
+ Frac256({0xa41178da4233dfdbULL, 0xfc55ac7cb3287dbcULL,
+ 0xa10ec1008799ec55ULL, 0x00000000000070dbULL}), // c_14
+ Frac256({0xbd533bacbc8f3ab8ULL, 0x93b765826d13ae70ULL,
+ 0xa26b9e7e2ce48e3fULL, 0x00000000000004e3ULL}), // c_15
+ Frac256({0xe33450363b8c0d3bULL, 0xc09a8ea3f919a324ULL,
+ 0x088968384b4faac9ULL, 0x0000000000000033ULL}), // c_16
+ Frac256({0x2bf8d71ab53ade5eULL, 0x48f9567d04173c92ULL,
+ 0xf7176bdb43695d72ULL, 0x0000000000000001ULL}), // c_17
+ Frac256({0x52f008e29e649d62ULL, 0x79d54d84b16ad619ULL,
+ 0x125a7ecb835b4a46ULL, 0x0000000000000000ULL}), // c_18
+ Frac256({0x3e1c2787b4d48f1bULL, 0x3588e474c82d686bULL,
+ 0x00a2d6625a829f19ULL, 0x0000000000000000ULL}), // c_19
+ Frac256({0x5e8c8f1088f16459ULL, 0xc735fd5e15f67f2eULL,
+ 0x00055ff17b41b4b0ULL, 0x0000000000000000ULL}), // c_20
+ Frac256({0xfd5b04031fd9182dULL, 0x8d6a9e1233c035ddULL,
+ 0x00002b59f51f6ec7ULL, 0x0000000000000000ULL}), // c_21
+};
+
+// Lookup table for 2^(i / 64) for i = 0..63 as Frac256.
+// Bit 255 represents 2^0 = 1, bits 254..0 represent the fractional part.
+// Generated by Sollya with:
+// > prec = 512;
+// > for i from 0 to 63 do {
+// v = round(2^(i / 64) * 2^255, 256, RN);
+// print(v);
+// };
+LIBC_INLINE_VAR constexpr Frac256 EXP2_MID_FRAC256[64] = {
+ Frac256({0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x8000000000000000ULL}),
+ Frac256({0xd08075ac1f200e4cULL, 0x9eb851655e2e5c4dULL,
+ 0x7be56527bd14def4ULL, 0x8164d1f3bc030773ULL}),
+ Frac256({0x2502f15067378a17ULL, 0x29f1a4afbefa5d7cULL,
+ 0x3e2a475b46520bffULL, 0x82cd8698ac2ba1d7ULL}),
+ Frac256({0x806bddad09d9c4a3ULL, 0x0d96b414ec4c9d06ULL,
+ 0x1af92eca13fd1582ULL, 0x843a28c3acde4046ULL}),
+ Frac256({0x5d42b362af1ee859ULL, 0x148a0459e7585151ULL,
+ 0xc5c95b8c2154c1b2ULL, 0x85aac367cc487b14ULL}),
+ Frac256({0x5229a7352c9b247bULL, 0x259ac58894f4fcb3ULL,
+ 0x3a1727c57b52a956ULL, 0x871f61969e8d1010ULL}),
+ Frac256({0x8bc3587fb118c94dULL, 0xe623d58b3772ba13ULL,
+ 0x5df8d76c98c67562ULL, 0x88980e8092da8527ULL}),
+ Frac256({0xe9c32d22e935007dULL, 0x259c4df53d76e910ULL,
+ 0x080ca1d92c3680c2ULL, 0x8a14d575496efd9aULL}),
+ Frac256({0x91e135ee84a3f734ULL, 0x1aa84ffbebac349fULL,
+ 0xfbe4628758a53c90ULL, 0x8b95c1e3ea8bd6e6ULL}),
+ Frac256({0x724a166325437476ULL, 0x183926ae7d718dc2ULL,
+ 0xb4c7b4968e41ad36ULL, 0x8d1adf5b7e5ba9e5ULL}),
+ Frac256({0xeb90ce3700bf59b6ULL, 0xa11037230b367828ULL,
+ 0x2dc0144c8783d4c5ULL, 0x8ea4398b45cd53c0ULL}),
+ Frac256({0x6f398dfe3f7903f1ULL, 0x43e90e15c2002132ULL,
+ 0x775814a8494e87e2ULL, 0x9031dc431466b1dcULL}),
+ Frac256({0xf1203caf65bfb9b9ULL, 0x1942b34816fb4f26ULL,
+ 0x0fd6d8e0ae5ac9d8ULL, 0x91c3d373ab11c336ULL}),
+ Frac256({0x583eab6852a22bb1ULL, 0x2748c36eeaffa273ULL,
+ 0xd339940e9d924ee7ULL, 0x935a2b2f13e6e92bULL}),
+ Frac256({0x035fb634c2e63a0fULL, 0x4856046901ff6c05ULL,
+ 0x2e8afad12551de54ULL, 0x94f4efa8fef70961ULL}),
+ Frac256({0x9a22b1526bb6a2e4ULL, 0xe0e68d9f200c5358ULL,
+ 0x48ea9b683a9c22c4ULL, 0x96942d3720185a00ULL}),
+ Frac256({0xd78b65cbefa7bb70ULL, 0x5e139a1b14fa8178ULL,
+ 0x46ad23182e42f6f6ULL, 0x9837f0518db8a96fULL}),
+ Frac256({0x1560e51a5df911dcULL, 0x8ac981ca9ceca6b3ULL,
+ 0xe43086cb34b5fcaeULL, 0x99e0459320b7fa64ULL}),
+ Frac256({0x9769d9b0a908a786ULL, 0x0928b5fce34cdf21ULL,
+ 0xa2a817a2a3cc3f1fULL, 0x9b8d39b9d54e5538ULL}),
+ Frac256({0x33a6fe2d4fd53e8aULL, 0x1ff17c29677589a0ULL,
+ 0xde494cf050e99b0bULL, 0x9d3ed9a72cffb750ULL}),
+ Frac256({0x21f977fe7c7fa118ULL, 0x65c15c122133e2a2ULL,
+ 0xa0911f09ebb9fdd1ULL, 0x9ef5326091a111adULL}),
+ Frac256({0x9f33f7bc78dc629fULL, 0x782a0735d02b1a20ULL,
+ 0x192dc79edb0fd9a9ULL, 0xa0b0510fb9714fc2ULL}),
+ Frac256({0x5a7a799221808de9ULL, 0x9da4384dbc2c8eaeULL,
+ 0x9b7a04ef80cfdea7ULL, 0xa27043030c496818ULL}),
+ Frac256({0x4c72418596cc5bd0ULL, 0xbae743abfbc07376ULL,
+ 0x0d1db4831781e1eeULL, 0xa43515ae09e6809eULL}),
+ Frac256({0x2589c98a8290d3f0ULL, 0x1dd170ace2bcfc17ULL,
+ 0x1cbd7f621710701bULL, 0xa5fed6a9b15138eaULL}),
+ Frac256({0xdd30939a1d1e929cULL, 0x01424bd194d3999eULL,
+ 0x9ec5b4d5039f72afULL, 0xa7cd93b4e9653569ULL}),
+ Frac256({0x325c9e2203504517ULL, 0x3951f214c02d824aULL,
+ 0x541e24ec3531fa73ULL, 0xa9a15ab4ea7c0ef8ULL}),
+ Frac256({0x967357d6b36df9f8ULL, 0x7ad59ec00ebe6393ULL,
+ 0x658023b2759e0079ULL, 0xab7a39b5a93ed337ULL}),
+ Frac256({0xb165f141833a67daULL, 0x6be409407034fdedULL,
+ 0x4980a8c8f59a2ec4ULL, 0xad583eea42a14ac6ULL}),
+ Frac256({0x5a8c73beaa946990ULL, 0xa4502c14f429ded9ULL,
+ 0xdf26101ccbb35032ULL, 0xaf3b78ad690a4374ULL}),
+ Frac256({0x97ced890d5b0b0c0ULL, 0x757cfb9913adc577ULL,
+ 0x87d037e96d215d8eULL, 0xb123f581d2ac258fULL}),
+ Frac256({0xba1e54cf684354dfULL, 0xfa6e051d6f8bc3ffULL,
+ 0x3ecf14dc798a519bULL, 0xb311c412a9112489ULL}),
+ Frac256({0xed17ac8583339915ULL, 0x1d6f60ba893ba84cULL,
+ 0x597d89b3754abe9fULL, 0xb504f333f9de6484ULL}),
+ Frac256({0x20850e774a86cd8fULL, 0xf88abbe777df360eULL,
+ 0x07165f0ddd541a59ULL, 0xb6fd91e328d17791ULL}),
+ Frac256({0x322d7893ed4da9a8ULL, 0xa5ab16cf451056edULL,
+ 0x1b879778566b65a1ULL, 0xb8fbaf4762fb9ee9ULL}),
+ Frac256({0x6c373a75c2828202ULL, 0x02f30d0bdcaa516dULL,
+ 0x74d519d24593838cULL, 0xbaff5ab2133e45fbULL}),
+ Frac256({0x0d9a4be023ece032ULL, 0x15b34bbcb0298f41ULL,
+ 0xa8811fb66d0faf7aULL, 0xbd08a39f580c36beULL}),
+ Frac256({0x83ea957596be426dULL, 0xa13fc7e6faf9c830ULL,
+ 0xe815d0abcbf0b850ULL, 0xbf1799b67a731082ULL}),
+ Frac256({0xdefefee72ae7a33dULL, 0x6b2e5dd607a9969cULL,
+ 0x7c457d59a50087b5ULL, 0xc12c4cca66709456ULL}),
+ Frac256({0x5b718d616c4fef19ULL, 0x6b9f89b7dabbcb2bULL,
+ 0x20ec856128b83a42ULL, 0xc346ccda24976407ULL}),
+ Frac256({0xc7686006e4e6c093ULL, 0x6b0f939998251a36ULL,
+ 0x3e2ad0c964dd9f37ULL, 0xc5672a115506daddULL}),
+ Frac256({0xcea65224bc9900d0ULL, 0x4da570a2c574a304ULL,
+ 0xc13a2e3976c0277eULL, 0xc78d74c8abb9b15cULL}),
+ Frac256({0xf4dd023ff93c7ffbULL, 0x257ac0db1f419377ULL,
+ 0x80e1f92a0511697eULL, 0xc9b9bd866e2f27a2ULL}),
+ Frac256({0x639aa6f940962626ULL, 0xeb8a25b7b40c0426ULL,
+ 0xf4907c8f45ebf6dcULL, 0xcbec14fef2727c5cULL}),
+ Frac256({0x2bbd398af35c079fULL, 0x6f28610b8c36485aULL,
+ 0xe235838f95f2c6edULL, 0xce248c151f8480e3ULL}),
+ Frac256({0x2a33269ab05c3e5dULL, 0x11546d3ea28976d6ULL,
+ 0xd6d45c6559a4d502ULL, 0xd06333daef2b2594ULL}),
+ Frac256({0xfa7663033f05357bULL, 0x52029c0b81f7be57ULL,
+ 0x12248e57c3de4028ULL, 0xd2a81d91f12ae45aULL}),
+ Frac256({0xfa628009459a2417ULL, 0xb8e7a32e5783da5cULL,
+ 0x5921deffa6262c5aULL, 0xd4f35aabcfedfa1fULL}),
+ Frac256({0xb5c13ada0e77829aULL, 0x1d733af522058b16ULL,
+ 0x39a68bb9902d3fdeULL, 0xd744fccad69d6af4ULL}),
+ Frac256({0xb70cfbb1bdf6eb5dULL, 0xc0edda4d891be43dULL,
+ 0xfe873deca3e12babULL, 0xd99d15c278afd7b5ULL}),
+ Frac256({0x613b0d1dbfa0d717ULL, 0x481e1ab725b12d56ULL,
+ 0x3d840d5a9e29aa64ULL, 0xdbfbb797daf23755ULL}),
+ Frac256({0xcc2490c8643ef6b4ULL, 0x01438495eacdf256ULL,
+ 0xdd07a2d9e8466859ULL, 0xde60f4825e0e9123ULL}),
+ Frac256({0x1cb99d3f1ff298a2ULL, 0x224b251b33092002ULL,
+ 0x065895048dd333caULL, 0xe0ccdeec2a94e111ULL}),
+ Frac256({0xfa8fcbb2e85b853fULL, 0xf358a8d368fceaeaULL,
+ 0x09bfe90795980eecULL, 0xe33f8972be8a5a51ULL}),
+ Frac256({0xcefcd5b62a14b818ULL, 0xaacd6065b6e9f6acULL,
+ 0x1e5e8f4a4edbb0ecULL, 0xe5b906e77c8348a8ULL}),
+ Frac256({0x3a1c6473409c261dULL, 0xfe312f84fa665204ULL,
+ 0x791790d0ac70c7ddULL, 0xe8396a503c4bdc68ULL}),
+ Frac256({0x17d8d1e8ca31880bULL, 0xc4faace043b7f91cULL,
+ 0xd02d75b3706e54faULL, 0xeac0c6e7dd24392eULL}),
+ Frac256({0xc8e7c95b06416e6dULL, 0x3787630a764ae4c9ULL,
+ 0x600d2db6a64bfb12ULL, 0xed4f301ed9942b84ULL}),
+ Frac256({0x9392870834f21a53ULL, 0xd4a277eaddaa925cULL,
+ 0x46561cf6948db912ULL, 0xefe4b99bdcdaf5cbULL}),
+ Frac256({0x7c43b0ea5d43228dULL, 0x2cf0b49df0bd70e9ULL,
+ 0xe8980a9cc8f47a4bULL, 0xf281773c59ffb139ULL}),
+ Frac256({0xbdd80329364aa2a0ULL, 0x6f510308677709f5ULL,
+ 0x7b9d0c7aed980fc3ULL, 0xf5257d152486cc2cULL}),
+ Frac256({0xef6797b5a11efb7cULL, 0xe914ffb4723793f1ULL,
+ 0xfe90d496d60fb6eaULL, 0xf7d0df730ad13bb8ULL}),
+ Frac256({0x4844b29bf4af18e8ULL, 0x8006fe21a95d14dcULL,
+ 0x7c25bb14315d7fccULL, 0xfa83b2db722a033aULL}),
+ Frac256({0x9d2285b6754edd61ULL, 0x061b7bb285a60791ULL,
+ 0x853f3a5931e0ee03ULL, 0xfd3e0c0cf486c174ULL}),
+};
+
+// Lookup table for -log2(RD[i]) for i = 0..127 as Frac256,
+// where RD[i] = 2^-8 * ceil(2^8 * (1 - 2^-8) / (1 + i * 2^-7)) is the argument
+// reduction constant from common_constants.h.
+// Generated by Sollya with:
+// > prec = 512;
+// > for i from 0 to 127 do {
+// rd = 2^(-8) * ceil(2^8 * (1 - 2^(-8)) / (1 + i * 2^(-7)));
+// v = round(-log2(rd) * 2^255, 256, RN);
+// print(v);
+// };
+LIBC_INLINE_VAR constexpr Frac256 LOG2_RD_FRAC256[128] = {
+ Frac256({0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x0000000000000000ULL}),
+ Frac256({0x6e26f44a7ba5ed8aULL, 0xd4a6b5a62ff68790ULL,
+ 0xb5d184a2c615b70aULL, 0x0172c7ba20f73275ULL}),
+ Frac256({0x262f5ca40b7fa26cULL, 0x3ea8c6b85ced9bdaULL,
+ 0xca906c23ef817e0bULL, 0x02e87dd0c3e6aac6ULL}),
+ Frac256({0x95b7f4fcee92de52ULL, 0xe775fc0ab1c9f028ULL,
+ 0x48f836042de0dc32ULL, 0x04612e39315abe0aULL}),
+ Frac256({0xa3a1e195dfe2d23bULL, 0xfc9f0716c9c77bc6ULL,
+ 0x7970e03f821c75d5ULL, 0x05dce53276563557ULL}),
+ Frac256({0xf021a80d769faed4ULL, 0x1dc18a2c9aa3711eULL,
+ 0x155660710eb2a091ULL, 0x075baf47c7faff81ULL}),
+ Frac256({0xa1c8545273e2d13eULL, 0x2c217796c1fcdb43ULL,
+ 0x631514aef39ce630ULL, 0x08dd9953002a4e86ULL}),
+ Frac256({0x75a862230522a2eaULL, 0xc18cf448bef176a4ULL,
+ 0x050799beaaab2940ULL, 0x0a62b07f3457c407ULL}),
+ Frac256({0x9e9fded86733d3caULL, 0xbaad60b1bf6bcd42ULL,
+ 0x9da288fc615a727dULL, 0x0beb024b67dda633ULL}),
+ Frac256({0x754ee58441dbf839ULL, 0xe1725598f1deb4d6ULL,
+ 0xf22dbbaced44516cULL, 0x0cb0657cd5dbe4f6ULL}),
+ Frac256({0xef894f2363f702c4ULL, 0x4cea550b2568cf82ULL,
+ 0x0d939dceecdd9ce0ULL, 0x0e3da945b878e27dULL}),
+ Frac256({0xe96924afd238c8c9ULL, 0x57c3feaa2020e02eULL,
+ 0x99596a8e2e84c8f4ULL, 0x0fce4aee0e88b274ULL}),
+ Frac256({0xb86f9d5aa2c46088ULL, 0xcc91d77315a3145bULL,
+ 0xa487dfb264b2a99fULL, 0x1097e38ce606492bULL}),
+ Frac256({0x6ffb458008d61f66ULL, 0x7d13d9c8e8a9007cULL,
+ 0xd23af3271ce44c70ULL, 0x122dadc2ab3496d2ULL}),
+ Frac256({0xc5b06c09a5744f6fULL, 0x2d931f14daa7bc7cULL,
+ 0x644ac793db28c412ULL, 0x13c6fb650cde50a1ULL}),
+ Frac256({0xb70ec311ae623b5fULL, 0x47a2302a7c41bfa9ULL,
+ 0xa74a794230202b5bULL, 0x1494f863b8df34baULL}),
+ Frac256({0x319dd5425ceb6df9ULL, 0x2cace034400340f2ULL,
+ 0xa7d70047ddacbac0ULL, 0x1633a8bf437ce10aULL}),
+ Frac256({0xbd7cbee513e8b29cULL, 0x623a9d853e546763ULL,
+ 0x19cb9577a5aea7b3ULL, 0x17046031c79f84beULL}),
+ Frac256({0xa214ecf13179e463ULL, 0x639cad5bff474c1aULL,
+ 0x6a9b7e2df60d2bdcULL, 0x18a8980abfbd3266ULL}),
+ Frac256({0x549b2f738887ca0dULL, 0x13e96e51cbcddd86ULL,
+ 0xaa32d50b40cf8ce7ULL, 0x197c1cb13c7ec085ULL}),
+ Frac256({0x0fc30982c995dbc4ULL, 0x0c5d7f995f1384d0ULL,
+ 0xde69308bc912aa0fULL, 0x1b2602497d53458cULL}),
+ Frac256({0x1766d8107cc2463bULL, 0xadedce27f01160b5ULL,
+ 0xf02bdee0b9f5de06ULL, 0x1bfc67a7fff4cc06ULL}),
+ Frac256({0x911ae4dceeb91543ULL, 0xa0018a21469a1f11ULL,
+ 0x4574e09b954ede83ULL, 0x1dac22d3e441d2feULL}),
+ Frac256({0x45b6ce87115cb69eULL, 0x603bb472c90ec7e1ULL,
+ 0xe40c5e6d7829a1b2ULL, 0x1e857d3d361367bdULL}),
+ Frac256({0xc2ae18e36f1a943bULL, 0xc2d3510c6f5fd964ULL,
+ 0x44ca200650512c0aULL, 0x203b3779f4c3a8bbULL}),
+ Frac256({0x5063aa93fcadc0b9ULL, 0x4805be54f509252bULL,
+ 0x552203798e04bf52ULL, 0x21179c1b2bf46fd8ULL}),
+ Frac256({0x6f2dba8b95f5c7c9ULL, 0x2079020c8a004162ULL,
+ 0x6a1f00babcdb8b0aULL, 0x22d380a6c7e2b0e4ULL}),
+ Frac256({0xe7d3c5ed0de90057ULL, 0x49c1a6f5afa47381ULL,
+ 0xa60108dfb23650c7ULL, 0x23b30593aa4e106bULL}),
+ Frac256({0x40b4cbc998adb82dULL, 0x1e4a0e0dbeb3195dULL,
+ 0x083e072a57679e5aULL, 0x24939a56279ad89aULL}),
+ Frac256({0x34552da7c8bea27fULL, 0xf185be16b7fcc49cULL,
+ 0x4492f1bc6b3e5770ULL, 0x2657fdc6e1dcd0cbULL}),
+ Frac256({0x6d3834bd854918b2ULL, 0xbb77e46da7b566d9ULL,
+ 0x5697a3886ffcccdaULL, 0x273bd1c2ab3edefeULL}),
+ Frac256({0xb402daaee365795fULL, 0x06e4fbd9714b80fbULL,
+ 0xd394fe8cca7d9625ULL, 0x2820c02f87d9451cULL}),
+ Frac256({0x9d7b13b46dda1849ULL, 0x885dce30d5e9e813ULL,
+ 0xc9d0b5ca5a8e7bb5ULL, 0x29edf7659d8b30f1ULL}),
+ Frac256({0x121032713a5003c9ULL, 0xe0b08724e7f04c97ULL,
+ 0x3cd6715512f1784cULL, 0x2ad645cd6af1c939ULL}),
+ Frac256({0x9c9cd255e7b18d6eULL, 0x58b9b632cfed6a65ULL,
+ 0x5adb21d3765b875dULL, 0x2bbfb9e3dd5c1c88ULL}),
+ Frac256({0x362e0218efac2fa7ULL, 0x10fb850fefe496c5ULL,
+ 0x4840199e302970e4ULL, 0x2caa569330c4eed6ULL}),
+ Frac256({0xb9254dfdf461e98cULL, 0x9a4ea80721314ac5ULL,
+ 0xdb502402c94092ccULL, 0x2d961ed0cb91d406ULL}),
+ Frac256({0xbeeea0c45c970f7eULL, 0x3bd29380bd1f0b11ULL,
+ 0xe278bad54ec9e6cfULL, 0x2f713e059e555a63ULL}),
+ Frac256({0x6f816641264b17aeULL, 0xf3f42009108dab4eULL,
+ 0x7561496ab4e4b293ULL, 0x30609b21823fa654ULL}),
+ Frac256({0x4429d9e262f3c8c6ULL, 0xc7395ab7fe8e9835ULL,
+ 0xd536fc5bec1a57b8ULL, 0x315130157f7a64ccULL}),
+ Frac256({0xd2f50c802ff2764aULL, 0xac331ec8776891deULL,
+ 0xe2357ab8cc98c9eeULL, 0x3243001249ba76feULL}),
+ Frac256({0x13bf99bcdd15e820ULL, 0x0c891fcfa03fdd31ULL,
+ 0x51b7e816f77f7b63ULL, 0x33360e552d8d64deULL}),
+ Frac256({0xc20d37d96d02df04ULL, 0x6d860cae2ed327dfULL,
+ 0x2ffa76fafcba2917ULL, 0x351ff2e30214bc30ULL}),
+ Frac256({0x85fb7f8ad3538e0dULL, 0x03d2c5dcbd9ccc4aULL,
+ 0x1ec47c7145831457ULL, 0x3616cfe9e8d01feaULL}),
+ Frac256({0x829c6e703f0fc512ULL, 0x0031e528bbef9eadULL,
+ 0xc4ce7959dfb11374ULL, 0x370ef8af6360dfdfULL}),
+ Frac256({0xe83c947d78828170ULL, 0xac2ed3668bc0c3b9ULL,
+ 0xfa8ae31eec3ba722ULL, 0x380870b3c5fb66f6ULL}),
+ Frac256({0x0cd67db0d807d403ULL, 0x0a9caaa68f883accULL,
+ 0x2bb1588cc9e47f8eULL, 0x39033b85a8bfc871ULL}),
+ Frac256({0x16420cec83688abaULL, 0x7b9e3ba7068f7b86ULL,
+ 0x1c5a0baeb329e73eULL, 0x39ff5cc235a256c5ULL}),
+ Frac256({0x65af196f4ce5b140ULL, 0x6a2513c4f89aa3a6ULL,
+ 0xa96b573a7ed69eedULL, 0x3afcd815786af187ULL}),
+ Frac256({0x319c80ace7918092ULL, 0x2ca495197c5993eaULL,
+ 0x8c8946414c6a14b1ULL, 0x3bfbb13ab0dc5613ULL}),
+ Frac256({0xe91dc50aab435aa9ULL, 0xe06bcb114a0f1719ULL,
+ 0xf6a2b59276887aabULL, 0x3cfbebfca715669dULL}),
+ Frac256({0x63d58c2be0e5b043ULL, 0x99a78444f0d00323ULL,
+ 0x930f8ba9f0570f47ULL, 0x3dfd8c36023f0ab6ULL}),
+ Frac256({0xd66a1a98fa3886e2ULL, 0x55226b72b74410b6ULL,
+ 0xaf2e6fea614b834dULL, 0x3f0095d1a19a0331ULL}),
+ Frac256({0x88c9482df3a84033ULL, 0x25aa4f7373799779ULL,
+ 0x670197a0e8f3ba74ULL, 0x40050ccaf800ca8cULL}),
+ Frac256({0x60ad16b1d436b2cfULL, 0x28336d5fee3ef522ULL,
+ 0xcd9cfff75e149b95ULL, 0x410af52e69f26263ULL}),
+ Frac256({0x14359d48fe9047deULL, 0x1991256093b9dc1cULL,
+ 0xc3fcaf8df7db7c03ULL, 0x42125319ae3bbf05ULL}),
+ Frac256({0x16fadce756865ed5ULL, 0xbae450ac5754344aULL,
+ 0x5cc3da171dd99950ULL, 0x431b2abc31565be7ULL}),
+ Frac256({0x8492c2612d5a8759ULL, 0x34ee848b0b781887ULL,
+ 0x89cd3dd41df9689bULL, 0x442580577b936762ULL}),
+ Frac256({0x3ad4311182915175ULL, 0x60c67a245f78bb52ULL,
+ 0x8283ccdf555594a0ULL, 0x4531583f9a2be203ULL}),
+ Frac256({0x5b3a3aef25dbcdefULL, 0xfdeb5563207896e0ULL,
+ 0x45eba230bf4dbea8ULL, 0x463eb6db8b4f066dULL}),
+ Frac256({0x32087d5975d8fe6bULL, 0xea99e677177c285cULL,
+ 0x02356a22199e7587ULL, 0x474da0a5ad495303ULL}),
+ Frac256({0x04a7b4a6562b4343ULL, 0xddd02924cf83def7ULL,
+ 0x77a639bfdd27aeb2ULL, 0x485e1a2c30df9ea9ULL}),
+ Frac256({0xe61b71e474e99f75ULL, 0x75abfd08dec73401ULL,
+ 0xd7220e04ebb0e2a4ULL, 0x497028118efabeb7ULL}),
+ Frac256({0x2a2437241ee48e55ULL, 0x8e16aa8188fd490aULL,
+ 0xb71b554e74851c3cULL, 0x4a83cf0d01c16e3cULL}),
+ Frac256({0xb80082d9fb082e0aULL, 0x67ff158637af6596ULL,
+ 0x077e50d0c2749c04ULL, 0x4b9913eb013f5ec5ULL}),
+ Frac256({0xb80082d9fb082e0aULL, 0x67ff158637af6596ULL,
+ 0x077e50d0c2749c04ULL, 0x4b9913eb013f5ec5ULL}),
+ Frac256({0x68aa5b4f917d44ffULL, 0xe30b7c2d6ff98938ULL,
+ 0x8925e378d67caee1ULL, 0x4caffb8dc3b9a196ULL}),
+ Frac256({0x642224ca9e7cc367ULL, 0xd122ba0a2e1a73faULL,
+ 0x9a95f528f2c754f3ULL, 0x4dc88aedc1d1ee96ULL}),
+ Frac256({0x313b1a081bc4ea73ULL, 0x09c491c06681cc48ULL,
+ 0x9336b66e4ac8a9deULL, 0x4ee2c71a3e9bb4b6ULL}),
+ Frac256({0x63d1c43831c10bdaULL, 0xf4272036db2b8f69ULL,
+ 0xa293ec16410a6ee4ULL, 0x4ffeb539d3c7579aULL}),
+ Frac256({0xd9740fe9e9c5253fULL, 0x1b73dad61ee48894ULL,
+ 0x202655dbb6b0071eULL, 0x511c5a8b02098837ULL}),
+ Frac256({0xd9740fe9e9c5253fULL, 0x1b73dad61ee48894ULL,
+ 0x202655dbb6b0071eULL, 0x511c5a8b02098837ULL}),
+ Frac256({0x2e147034099ccfcfULL, 0xb03b7d7e6bd0493fULL,
+ 0xe55be97611f87779ULL, 0x523bbc64c5e64350ULL}),
+ Frac256({0x58e4c41655df5f19ULL, 0x740e9519cc12e4a0ULL,
+ 0xbb0e246ec2cef169ULL, 0x535ce0373108b235ULL}),
+ Frac256({0x0834df65b40b7c12ULL, 0xb61832b8bb4c9f7fULL,
+ 0xbfe9dbebf2e8a45dULL, 0x547fcb8c0852f0c0ULL}),
+ Frac256({0x8b32b1fbdcbd3f0cULL, 0x4408786d49566334ULL,
+ 0x613e33c06c95a688ULL, 0x55a4840766d29904ULL}),
+ Frac256({0xdc92a6fefa30f4c6ULL, 0x4d2754039098a562ULL,
+ 0x6da8120164a04966ULL, 0x56cb0f6865c8ea03ULL}),
+ Frac256({0xdc92a6fefa30f4c6ULL, 0x4d2754039098a562ULL,
+ 0x6da8120164a04966ULL, 0x56cb0f6865c8ea03ULL}),
+ Frac256({0x313af26502f8a6cdULL, 0x8dff0ebab8d36942ULL,
+ 0x9a1977b5b995b421ULL, 0x57f37389c9f76d14ULL}),
+ Frac256({0x2d7c1749f6f423c0ULL, 0xdf64485cf695a7a3ULL,
+ 0xdd9926d3f02373c8ULL, 0x591db662b664264cULL}),
+ Frac256({0xaa7293ec76e59d5bULL, 0xc74c7f4741bb1f6fULL,
+ 0xd90b84e721864711ULL, 0x5a49de0764caa121ULL}),
+ Frac256({0xaa7293ec76e59d5bULL, 0xc74c7f4741bb1f6fULL,
+ 0xd90b84e721864711ULL, 0x5a49de0764caa121ULL}),
+ Frac256({0xf662658135c18184ULL, 0x5f0bcac4e6cfec7bULL,
+ 0x748d68b767f88088ULL, 0x5b77f0a9e3f18cfbULL}),
+ Frac256({0x80348894da13c701ULL, 0x49c65b1a5a602129ULL,
+ 0xe718f240e6bcbf3cULL, 0x5ca7f49adc1f1f5aULL}),
+ Frac256({0xdce91e02b40b35d8ULL, 0xc46327805ec0076cULL,
+ 0xed1f4b0d4b62c07cULL, 0x5dd9f04a59e91469ULL}),
+ Frac256({0xdce91e02b40b35d8ULL, 0xc46327805ec0076cULL,
+ 0xed1f4b0d4b62c07cULL, 0x5dd9f04a59e91469ULL}),
+ Frac256({0x5f884b8ddadcf74dULL, 0xf5e3dadf04bd0ff3ULL,
+ 0xf9cb2cc55748a4ccULL, 0x5f0dea489f9fed21ULL}),
+ Frac256({0xa609c77144ded04cULL, 0xb30a91252b56f94aULL,
+ 0x572667587b10ca0dULL, 0x6043e946fd97f5dcULL}),
+ Frac256({0xa609c77144ded04cULL, 0xb30a91252b56f94aULL,
+ 0x572667587b10ca0dULL, 0x6043e946fd97f5dcULL}),
+ Frac256({0xf93ce8eff413527cULL, 0x8554c2c17f944fa1ULL,
+ 0x360c2ae2103c7c0dULL, 0x617bf418b195b338ULL}),
+ Frac256({0x7b3285d76164c890ULL, 0x07d4b4b5500472a5ULL,
+ 0x0b4a9afdc5fabbe4ULL, 0x62b611b3cda69037ULL}),
+ Frac256({0x7b3285d76164c890ULL, 0x07d4b4b5500472a5ULL,
+ 0x0b4a9afdc5fabbe4ULL, 0x62b611b3cda69037ULL}),
+ Frac256({0x599f2a65c6ef7dd4ULL, 0x3edbea325add2accULL,
+ 0x1d9267663010bca1ULL, 0x63f2493226b211bfULL}),
+ Frac256({0x5509d9aded608bccULL, 0xdf7d4115ebc0ee87ULL,
+ 0x1ee1343fe7c9cb4aULL, 0x6530a1d24b136c10ULL}),
+ Frac256({0x5509d9aded608bccULL, 0xdf7d4115ebc0ee87ULL,
+ 0x1ee1343fe7c9cb4aULL, 0x6530a1d24b136c10ULL}),
+ Frac256({0x063711bbcff6a7caULL, 0x34bf67662d61c015ULL,
+ 0x05317356e8d480d0ULL, 0x667122f8818f20fdULL}),
+ Frac256({0xdb09e5e814c87f43ULL, 0x829344b50240232cULL,
+ 0x2ddb71189c56a8f0ULL, 0x67b3d42fd0fc4d02ULL}),
+ Frac256({0xdb09e5e814c87f43ULL, 0x829344b50240232cULL,
+ 0x2ddb71189c56a8f0ULL, 0x67b3d42fd0fc4d02ULL}),
+ Frac256({0x4c8dec7f0307142cULL, 0xca3b2dcc7941a5dfULL,
+ 0x3fe30528818495d6ULL, 0x68f8bd2b10fd80d6ULL}),
+ Frac256({0x841a6fb2da05be09ULL, 0xdb0c195c5da64fbfULL,
+ 0x5ff4edf5f974522eULL, 0x6a3fe5c604297860ULL}),
+ Frac256({0x841a6fb2da05be09ULL, 0xdb0c195c5da64fbfULL,
+ 0x5ff4edf5f974522eULL, 0x6a3fe5c604297860ULL}),
+ Frac256({0x6f295eb94b4ff3f4ULL, 0x524c383b17757feeULL,
+ 0xc716be9bc093ec11ULL, 0x6b8956067c08b2ceULL}),
+ Frac256({0xd50c7b85bba151bcULL, 0x6ac0ed3b39116e44ULL,
+ 0xae0d3f8a58b459b2ULL, 0x6cd5161d8751e5e0ULL}),
+ Frac256({0xd50c7b85bba151bcULL, 0x6ac0ed3b39116e44ULL,
+ 0xae0d3f8a58b459b2ULL, 0x6cd5161d8751e5e0ULL}),
+ Frac256({0xcee3b58a450ab308ULL, 0x7822b754be5b62abULL,
+ 0x5babcf87c69ea8a5ULL, 0x6e232e68aad484a1ULL}),
+ Frac256({0xcee3b58a450ab308ULL, 0x7822b754be5b62abULL,
+ 0x5babcf87c69ea8a5ULL, 0x6e232e68aad484a1ULL}),
+ Frac256({0x7ea793f02baad929ULL, 0xb0c4015f8fdff17dULL,
+ 0xd843902f5aad7542ULL, 0x6f73a77325861c69ULL}),
+ Frac256({0xe19972fa315f9621ULL, 0xd5e23a4c7b4973b0ULL,
+ 0xa1251311eb06fd8aULL, 0x70c689f7402d26f1ULL}),
+ Frac256({0xe19972fa315f9621ULL, 0xd5e23a4c7b4973b0ULL,
+ 0xa1251311eb06fd8aULL, 0x70c689f7402d26f1ULL}),
+ Frac256({0xab2afce4184639aeULL, 0x4df1d7bf78e23ef9ULL,
+ 0x269d2c8d7342a3c3ULL, 0x721bdedfa92a22ceULL}),
+ Frac256({0xab2afce4184639aeULL, 0x4df1d7bf78e23ef9ULL,
+ 0x269d2c8d7342a3c3ULL, 0x721bdedfa92a22ceULL}),
+ Frac256({0x261c1d2c4d56a905ULL, 0xb94dd8c8f0834794ULL,
+ 0xc6e6db59262e2e6fULL, 0x7373af48dce652a8ULL}),
+ Frac256({0xdb6ddbdb00d73945ULL, 0x1ad7c182a716c033ULL,
+ 0x99d63ecf5dd4529eULL, 0x74ce04829b7674c1ULL}),
+ Frac256({0xdb6ddbdb00d73945ULL, 0x1ad7c182a716c033ULL,
+ 0x99d63ecf5dd4529eULL, 0x74ce04829b7674c1ULL}),
+ Frac256({0x22ba4e8b413991d3ULL, 0x95b97a0e1d121d02ULL,
+ 0xfd9776f25acec4acULL, 0x762ae8116c071e93ULL}),
+ Frac256({0x22ba4e8b413991d3ULL, 0x95b97a0e1d121d02ULL,
+ 0xfd9776f25acec4acULL, 0x762ae8116c071e93ULL}),
+ Frac256({0x7420ca3f82a950a2ULL, 0xa3757861c1116ee5ULL,
+ 0x1845a2a3336f47ccULL, 0x778a63b02eb032a6ULL}),
+ Frac256({0x7420ca3f82a950a2ULL, 0xa3757861c1116ee5ULL,
+ 0x1845a2a3336f47ccULL, 0x778a63b02eb032a6ULL}),
+ Frac256({0x481eb4627658b4afULL, 0x16a73e812a9e4565ULL,
+ 0xc1c1e586711df5eaULL, 0x78ec8151bd552842ULL}),
+ Frac256({0x481eb4627658b4afULL, 0x16a73e812a9e4565ULL,
+ 0xc1c1e586711df5eaULL, 0x78ec8151bd552842ULL}),
+ Frac256({0xfce168eaef943079ULL, 0xce4c86d28e4be331ULL,
+ 0xb27e43da520fbdb7ULL, 0x7a514b229c409e33ULL}),
+ Frac256({0xfce168eaef943079ULL, 0xce4c86d28e4be331ULL,
+ 0xb27e43da520fbdb7ULL, 0x7a514b229c409e33ULL}),
+ Frac256({0x59576b46a119898aULL, 0x254008aeb4167a33ULL,
+ 0x9faebec15b2e2b43ULL, 0x7bb8cb8abb32fb44ULL}),
+ Frac256({0x59576b46a119898aULL, 0x254008aeb4167a33ULL,
+ 0x9faebec15b2e2b43ULL, 0x7bb8cb8abb32fb44ULL}),
+ Frac256({0x10e7d4a6c2ef9745ULL, 0x3ead121a489569ffULL,
+ 0xb23b03bdcfdea0d7ULL, 0x7d230d2f47a5baceULL}),
+ Frac256({0x10e7d4a6c2ef9745ULL, 0x3ead121a489569ffULL,
+ 0xb23b03bdcfdea0d7ULL, 0x7d230d2f47a5baceULL}),
+ Frac256({0xa828a9bde1ec7e79ULL, 0xe33209b70d9a5be1ULL,
+ 0x071c84ffe86b0bbbULL, 0x7e901af4910f7ae8ULL}),
+ Frac256({0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x8000000000000000ULL}),
+};
+
+// Accurate log2(x) in 256-bit precision reusing range reduction from fast pass:
+// x = 2^x_e * m_x, with 1 <= m_x < 2
+// r = RD[idx_x]
+// dx = r * m_x - 1, with -2^-8 <= dx < 2^-7
+// log2(x) = x_e + (-log2(r)) + log2(1 + dx).
+// The value -log2(r) is provided by LOG2_RD_FRAC256[idx_x].
+// log2(1 + dx) is evaluated with a degree-30 minimax polynomial using a 3-tier
+// Horner scheme (Frac64, Frac128, and Frac256).
+LIBC_INLINE DFloat256 log2_f256(int x_e, unsigned idx_x, double dx) {
+ using FPBits = fputil::FPBits<double>;
+
+ if (dx == 0.0) {
+ Frac256 log2_m = LOG2_RD_FRAC256[idx_x];
+ DFloat256 m_df(Sign::POS, -255, log2_m);
+ return fputil::quick_add(DFloat256(static_cast<double>(x_e)), m_df);
+ }
+
+ double abs_dx = (dx < 0.0) ? -dx : dx;
+ FPBits bits(abs_dx);
+ // Append hidden bit.
+ uint64_t mant = bits.get_mantissa() | (1ULL << 52);
+ int shift = 255 + bits.get_exponent() - 52;
+ Frac256 y =
+ (shift >= 0) ? Frac256((UInt<256>(mant) << shift).val) : Frac256(0);
+
+ // Evaluate log2(1 + dx) using Horner scheme in 3 stages:
+ // - Degree 18-30: 64-bit precision evaluation.
+ // - Degree 8-17: 128-bit precision evaluation.
+ // - Degree 0-7: 256-bit precision evaluation.
+ //
+ // Since y = |dx| <= 2^-7, truncation errors at degree k is bounded by:
+ // y^k <= 2^(-7k).
+ //
+ // Step 1: 64-bit evaluation, truncation error at degree 18 is bounded by:
+ // 2^-63 * y^18 <= 2^-189.
+ Frac64 y64 = y.to_frac64();
+ Frac64 p64 = LOG2_POLY_256[30].to_frac64();
+ if (dx >= 0.0) {
+ for (int k = 29; k >= 18; --k)
+ p64 = LOG2_POLY_256[k].to_frac64() - ((p64 * y64) << 1);
+ } else {
+ for (int k = 29; k >= 18; --k)
+ p64 = LOG2_POLY_256[k].to_frac64() + ((p64 * y64) << 1);
+ }
+
+ // Step 2: 128-bit evaluation, truncation error at degree 8 is bounded by:
+ // 2^-127 * y^8 <= 2^-183.
+ Frac128 y128 = y.to_frac128();
+ Frac128 p128({0, p64.val[0]});
+ if (dx >= 0.0) {
+ for (int k = 17; k >= 8; --k)
+ p128 = LOG2_POLY_256[k].to_frac128() - ((p128 * y128) << 1);
+ } else {
+ for (int k = 17; k >= 8; --k)
+ p128 = LOG2_POLY_256[k].to_frac128() + ((p128 * y128) << 1);
+ }
+
+ // Step 3: 256-bit evaluation.
+ Frac256 p({0, 0, p128.val[0], p128.val[1]});
+ if (dx >= 0.0) {
+ for (int k = 7; k >= 0; --k)
+ p = LOG2_POLY_256[k] - ((p * y) << 1);
+ } else {
+ for (int k = 7; k >= 0; --k)
+ p = LOG2_POLY_256[k] + ((p * y) << 1);
+ }
+
+ // log2(1 + dx) = 2 * y * P(y):
+ Frac256 log2_1p = (y * p) << 2;
+ Frac256 log2_rd = LOG2_RD_FRAC256[idx_x];
+ Frac256 log2_m = (dx >= 0.0) ? (log2_rd + log2_1p) : (log2_rd - log2_1p);
+
+ DFloat256 m_df(Sign::POS, -255, log2_m);
+ return fputil::quick_add(DFloat256(static_cast<double>(x_e)), m_df);
+}
+
+// Range reduction:
+// k = round(z * 64)
+// hi = k >> 6
+// idx = k & 0x3f
+// lo = z - k * 2^-6, with |lo| <= 2^-7.
+// Then:
+// 2^z = 2^hi * EXP2_MID_FRAC256[idx] * 2^lo
+// = 2^hi * EXP2_MID_FRAC256[idx] * (1 + lo * P(lo)).
+LIBC_INLINE DFloat256 exp2_f256(const DFloat256 &z) {
+ double z_d = static_cast<double>(z);
+ double z_scaled = z_d * 64.0;
+ double kd = fputil::nearest_integer(z_scaled);
+ int k = static_cast<int>(kd);
+
+ int hi = k >> 6;
+ unsigned idx = static_cast<unsigned>(k & 0x3f);
+
+ DFloat256 kd_f256(kd * 0x1.0p-6);
+ DFloat256 lo = fputil::quick_add(z, -kd_f256);
+
+ Frac256 m = EXP2_MID_FRAC256[idx];
+ if (LIBC_UNLIKELY(lo.mantissa.is_zero()))
+ return DFloat256(Sign::POS, hi - 255, m);
+
+ bool lo_is_neg = (lo.sign == Sign::NEG);
+ int shift = -255 - lo.exponent;
+ Frac256 u = (shift < 256) ? Frac256((lo.mantissa >> shift).val) : Frac256(0);
+
+ // Evaluate 2^lo - 1 = lo * P(lo) using Horner scheme in 3 stages:
+ // - Degree 12-21: 64-bit precision evaluation.
+ // - Degree 6-11: 128-bit precision evaluation.
+ // - Degree 0-5: 256-bit precision evaluation.
+ //
+ // Since u = |lo| <= 2^-7, truncation errors at degree i is bounded by:
+ // u^i <= 2^(-7i).
+ //
+ // Step 1: 64-bit evaluation, truncation error at degree 12 is bounded by:
+ // 2^-63 * u^12 <= 2^-147.
+ Frac64 u64 = u.to_frac64();
+ Frac64 p64 = EXP2_POLY_256[21].to_frac64();
+ if (lo_is_neg) {
+ for (int i = 20; i >= 12; --i)
+ p64 = EXP2_POLY_256[i].to_frac64() - ((p64 * u64) << 1);
+ } else {
+ for (int i = 20; i >= 12; --i)
+ p64 = EXP2_POLY_256[i].to_frac64() + ((p64 * u64) << 1);
+ }
+
+ // Step 2: 128-bit evaluation, truncation error at degree 6 is bounded by:
+ // 2^-127 * u^6 <= 2^-169.
+ Frac128 u128 = u.to_frac128();
+ Frac128 p128({0, p64.val[0]});
+ if (lo_is_neg) {
+ for (int i = 11; i >= 6; --i)
+ p128 = EXP2_POLY_256[i].to_frac128() - ((p128 * u128) << 1);
+ } else {
+ for (int i = 11; i >= 6; --i)
+ p128 = EXP2_POLY_256[i].to_frac128() + ((p128 * u128) << 1);
+ }
+
+ // Step 3: 256-bit evaluation.
+ Frac256 p({0, 0, p128.val[0], p128.val[1]});
+ if (lo_is_neg) {
+ for (int i = 5; i >= 0; --i)
+ p = EXP2_POLY_256[i] - ((p * u) << 1);
+ } else {
+ for (int i = 5; i >= 0; --i)
+ p = EXP2_POLY_256[i] + ((p * u) << 1);
+ }
+
+ // Reconstruction:
+ // t = u * P(u) ~ 2^u - 1 as Frac256
+ // mt = m * t ~ m * (2^u - 1) as Frac256
+ // m_final = m +- mt ~ m * (1 +- t) ~ m * 2^lo
+ Frac256 t = (u * p) << 1;
+ Frac256 mt = (m * t) << 1;
+ Frac256 m_final = lo_is_neg ? (m - mt) : (m + mt);
+
+ if ((m_final.val[3] & (1ULL << 63)) == 0) {
+ m_final = m_final << 1;
+ --hi;
+ }
+
+ return DFloat256(Sign::POS, hi - 255, m_final);
+}
+
+// Accurate pow(x, y) reusing range reduction parameters in 256-bit precision.
+// Lauter & Lefevre (2009) showed that if x^y is not an exact 54-bit number, the
+// distance to the nearest 54-bit boundary is at least:
+// |x^y - o_54(x^y)| / x^y >= 2^-114.
+// Since exact 54-bit boundaries are already handled in pow_accurate, the
+// 256-bit evaluation with error < 2^-250 is sufficient to correctly round all
+// remaining cases.
+LIBC_INLINE double pow_accurate_256(double y, bool is_neg, int x_e,
+ unsigned idx_x, double dx) {
+ DFloat256 log2_x = log2_f256(x_e, idx_x, dx);
+ DFloat256 y_f256(y);
+ DFloat256 z = fputil::quick_mul(y_f256, log2_x);
+
+ // For 0 < |z| <= 2^-55, x^y is between 1 - 2^-54 and 1 + 2^-53.
+ if (LIBC_UNLIKELY(!z.mantissa.is_zero() && z.exponent + 255 <= -55)) {
+ volatile double one = 1.0;
+ volatile double eps = (z.sign == Sign::NEG) ? -0x1.0p-100 : 0x1.0p-100;
+ double res = one + eps;
+ return is_neg ? -res : res;
+ }
+
+ DFloat256 r = exp2_f256(z);
+ if (is_neg)
+ r.sign = Sign::NEG;
+
+ int unbiased_exp = r.exponent + 255;
+ if (LIBC_UNLIKELY(unbiased_exp >= 1024))
+ return set_overflow(is_neg);
+
+ double res = static_cast<double>(r);
+ if (LIBC_UNLIKELY(fputil::FPBits<double>(res).is_inf()))
+ return set_overflow(is_neg);
+
+ return res;
+}
+
+} // namespace pow_internal
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_POW_ACCURATE_256_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_fast.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_fast.h
new file mode 100644
index 00000000000..5960bea6064
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_fast.h
@@ -0,0 +1,304 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Fast implementation header for double-precision pow(x, y).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POW_FAST_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_POW_FAST_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/common_constants.h"
+#include "src/__support/math/exp_constants.h"
+#include "src/__support/math/pow_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE double pow(double x, double y) {
+ using namespace pow_internal;
+ using FPBits = fputil::FPBits<double>;
+
+ FPBits xbits(x), ybits(y);
+ uint64_t x_u = xbits.uintval();
+ uint64_t y_u = ybits.uintval();
+ uint64_t y_a = ybits.abs().uintval();
+
+ if (LIBC_UNLIKELY((x_u & 0x0003'FFFF'FFFF'FFFF) == 0 ||
+ (y_u & 0x000F'FFFF'FFFF'FFFF) == 0)) {
+ if (auto r = check_special_inputs(x, y); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+
+ double e_x = static_cast<double>(xbits.get_exponent());
+ uint64_t x_mant = xbits.get_mantissa();
+ bool is_neg = false;
+ double sign_d = 1.0;
+
+ if (LIBC_UNLIKELY(y_a <= Y_LOWER_BOUND || y_a >= Y_UPPER_BOUND ||
+ x_u >= FPBits::inf().uintval() ||
+ x_u < FPBits::min_normal().uintval())) {
+ if (auto r = check_exceptional_cases(x, y, e_x, x_mant, is_neg, sign_d);
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+
+ // x^y = 2^( y * log2(x) )
+ // = 2^( y * ( e_x + log2(m_x) ) )
+ // First we compute log2(x) = e_x + log2(m_x)
+
+ // Extract exponent field of x.
+
+ // Use the highest 7 fractional bits of m_x as the index for look up tables.
+ unsigned idx_x = static_cast<unsigned>(x_mant >> (FPBits::FRACTION_LEN - 7));
+ // Add the hidden bit to the mantissa.
+ // 1 <= m_x < 2
+ FPBits m_x = FPBits(x_mant | 0x3ff0'0000'0000'0000);
+
+ // Reduced argument for log2(m_x):
+ // dx = r * m_x - 1.
+ // The computation is exact, and -2^-8 <= dx < 2^-7.
+ // Then m_x = (1 + dx) / r, and
+ // log2(m_x) = log2( (1 + dx) / r )
+ // = log2(1 + dx) - log2(r).
+
+ // See the overview comment in pow.h for the detailed error analysis.
+ // To ensure the relative error is strictly < 1 ULP across the entire double
+ // precision range, we evaluate the prefix log2(e) * (dx - dx^2/2) accurately
+ // using DoubleDouble (n = 2), and approximate higher terms with dx^3 * P(dx).
+
+ // Constants for C_k = (-1)^(k-1) / (k * log(2)) in DoubleDouble:
+ // C1 = 1 / log(2) = log2(e)
+ constexpr DoubleDouble C1 = {0x1.777d0ffda0d24p-56, 0x1.71547652b82fep0};
+ // C2 = -1 / (2 * log(2)) = -log2(e) / 2
+ constexpr DoubleDouble C2 = {-0x1.777d0ffda0d24p-57, -0x1.71547652b82fep-1};
+
+ // Degree-5 polynomial approximation for:
+ // P(dx) ~ (log2(1 + dx) - (dx - dx^2/2) / log(2)) / dx^3
+ // Generated by Sollya with:
+ // > P = fpminimax((log2(1 + x) - (x - x^2/2)/log(2))/x^3, 5, [|D...|],
+ // [-2^-8, 2^-7]);
+ // > dirtyinfnorm((log2(1 + x) - (x - x^2/2)/log(2))/x - x^2*P,
+ // [-2^-8, 2^-7]);
+ // 0x1.cfc09...p-67
+ constexpr double COEFFS[] = {
+ 0x1.ec709dc3a03fcp-2, -0x1.71547652b7546p-2, 0x1.2776c50fc020bp-2,
+ -0x1.ec70a327cae39p-3, 0x1.a616f87d961abp-3, -0x1.6d89893e348ddp-3,
+ };
+
+ // Perform exact range reduction.
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double dx = fputil::multiply_add(RD[idx_x], m_x.get_val(), -1.0); // Exact
+#else
+ double c = FPBits(m_x.uintval() & 0x3fff'e000'0000'0000).get_val();
+ double dx =
+ fputil::multiply_add(RD[idx_x], m_x.get_val() - c, CD[idx_x]); // Exact
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ // Error-free transformation for r = C1 + dx * C2:
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double r_hi = fputil::multiply_add(dx, C2.hi, C1.hi);
+ double r_lo = fputil::multiply_add(dx, C2.hi, C1.hi - r_hi);
+#else
+ DoubleDouble dx_c2 = fputil::exact_mult(dx, C2.hi);
+ DoubleDouble r_sum = fputil::exact_add(C1.hi, dx_c2.hi);
+ double r_hi = r_sum.hi;
+ double r_lo = r_sum.lo + dx_c2.lo;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ r_lo = fputil::multiply_add(dx, C2.lo, r_lo + C1.lo);
+
+ // dx * (r_hi + r_lo) = dx * C1 + dx^2 * C2
+ DoubleDouble dx_r = fputil::exact_mult(dx, r_hi);
+ dx_r.lo = fputil::multiply_add(dx, r_lo, dx_r.lo);
+
+ // Evaluate polynomial tail P(dx) using Estrin's scheme:
+ double dx2 = dx * dx;
+ double c0 = fputil::multiply_add(dx, COEFFS[1], COEFFS[0]);
+ double c1 = fputil::multiply_add(dx, COEFFS[3], COEFFS[2]);
+ double c2 = fputil::multiply_add(dx, COEFFS[5], COEFFS[4]);
+
+ double dx4 = dx2 * dx2;
+ double d0 = fputil::multiply_add(dx2, c1, c0);
+ double p = fputil::multiply_add(dx4, c2, d0);
+
+ double dx3 = dx2 * dx;
+ double log2_x_lo =
+ fputil::multiply_add(dx3, p, dx_r.lo + LOG2_R_DD[idx_x].lo);
+
+ DoubleDouble log2_x_hi =
+ fputil::exact_add(e_x + LOG2_R_DD[idx_x].hi, dx_r.hi);
+
+ DoubleDouble log2_x = fputil::exact_add(log2_x_hi.hi, log2_x_lo);
+ log2_x.lo += log2_x_hi.lo;
+
+ // To compute 2^(y * log2(x)), we break the exponent into 3 parts:
+ // y * log2(x) = hi + mid + lo, where
+ // hi is an integer
+ // mid * 2^6 is an integer
+ // |lo| <= 2^-7
+ // Then:
+ // x^y = 2^(y * log2(x)) = 2^hi * 2^mid * 2^lo,
+ // In which 2^mid is obtained from a look-up table of size 2^6 = 64 elements,
+ // and 2^lo ~ 1 + lo * P(lo).
+ // Thus, we have:
+ // hi + mid = 2^-6 * round( 2^6 * y * log2(x) )
+ // If we restrict the output such that |hi| < 512, (hi + mid) uses (9 + 6)
+ // bits, hence, if we use double precision to perform
+ // round( 2^6 * y * log2(x))
+ // the lo part is bounded by 2^-7 + 2^(-(52 - 15)) = 2^-7 + 2^-37
+
+ // In the following computations:
+ // y6 = 2^6 * y
+ // hm = 2^6 * (hi + mid) = round(2^6 * y * log2(x)) ~ round(y6 * s)
+ // lo6 = 2^6 * lo = 2^6 * (y - (hi + mid)) = y6 * log2(x) - hm.
+ constexpr double SCALE = 0x1.0p6;
+ double y6 = y * SCALE; // Exact.
+
+ DoubleDouble y6_log2_x = fputil::exact_mult(y6, log2_x.hi);
+ y6_log2_x.lo = fputil::multiply_add(y6, log2_x.lo, y6_log2_x.lo);
+
+ // Check overflow/underflow.
+ double scale = 1.0;
+
+ // |2^(hi + mid) - exp2_hi_mid| <= ulp(exp2_hi_mid) / 2
+
+ // The fast computation for 2^hi below requires that:
+ // |hi| < 512, or equivalently, |hm| < 512 * 2^6.
+ // This guarantees that the biased exponent:
+ // exp_biased = (hm_i >> 6) + EXP_BIAS = hi + 1023
+ // is strictly within the normal double range:
+ // 1023 - 511 <= exp_biased <= 1023 + 511, or 512 <= exp_biased <= 1534.
+ // Hence, 2^hi is always a normal, non-zero, finite power of 2, and the
+ // multiplication upper * exp2_hi is exact and never underflows or overflows.
+ //
+ // From the edge case checks above:
+ // 2^(-54) / 1074 <= |y| <= 1075 * 2^53, and
+ // |log_2(1 - 2^(-53))| <= |log2(x)| <= 1074.
+ // So their product is bounded by:
+ // 2^-117 < |y * log2(x)| < 2^74.
+ //
+ // The meaningful range for y * log2(x) in double precision is:
+ // -1075 <= y * log2(x) <= 1024.
+ // Any value > 1024 overflows, and any value < -1075 underflows.
+ //
+ // When |y * log2(x)| >= 511, we shift the exponent by an offset S:
+ // y * log2(x) = (y * log2(x) - S) + S
+ // and multiply by scale = 2^S at the end.
+ // To ensure the shifted exponent (y * log2(x) - S) stays within [-511, 511]:
+ // - For positive range [511, 1024]:
+ // 511 - S > -511 ==> S < 1022
+ // 1024 - S < 511 ==> S > 513
+ // - For negative range [-1076, -511]:
+ // -511 + S < 511 ==> S <= 1022
+ // -1076 + S > -511 ==> S >= 565
+ // Combined, the shift must satisfy: 565 <= S <= 1022.
+ // We choose S = 600, which yields:
+ // y * log2(x) - 600 in [-89, 424] for the positive range, and
+ // y * log2(x) + 600 in [-476, 89] for the negative range,
+ // both fitting well within [-511, 511].
+ //
+ // For exponents that are completely out of range:
+ // y * log2(x) > 1024 or y * log2(x) < -1076,
+ // the product can be as large as 2^74, so subtracting or adding 600 * 64
+ // would still overflow a 32-bit int when computing hm_i.
+ // We return early with overflow or underflow in these cases.
+ //
+ // Alternatively, for less branching or in SIMD / vector implementations, one
+ // could clamp y6_log2_x.hi to:
+ // - UPPER_EXP_BOUND (511 * 64) for overflow, which when multiplied by
+ // scale = 2^600 yields 2^1111 and correctly overflows.
+ // - -500 * 64 for underflow, which when multiplied by scale = 2^-600 yields
+ // 2^-1100 and correctly underflows.
+ // Note that in a correctly rounded version, such clamping can cause the
+ // Ziv accuracy test to fail on the clamped exponent, unnecessarily
+ // triggering the slow accurate paths for overflow or underflow cases.
+
+ constexpr double UPPER_EXP_BOUND = 511.0 * SCALE;
+ if (LIBC_UNLIKELY(FPBits(y6_log2_x.hi).abs().get_val() >= UPPER_EXP_BOUND)) {
+ if (FPBits(y6_log2_x.hi).sign() == Sign::POS) {
+ if (y6_log2_x.hi > 1024.0 * SCALE)
+ return set_overflow(is_neg);
+ scale = 0x1.0p600;
+ y6_log2_x.hi -= 600.0 * SCALE;
+ } else {
+ if (y6_log2_x.hi < -1076.0 * SCALE)
+ return set_underflow(is_neg);
+ scale = 0x1.0p-600;
+ y6_log2_x.hi += 600.0 * SCALE;
+ }
+ }
+
+ double hm = fputil::nearest_integer(y6_log2_x.hi);
+
+ // lo6 = 2^6 * lo.
+ DoubleDouble lo6 = fputil::exact_add(y6_log2_x.hi - hm, y6_log2_x.lo);
+
+ int hm_i = static_cast<int>(hm);
+ unsigned idx_y = static_cast<unsigned>(hm_i) & 0x3f;
+
+ // 2^hi
+ int64_t exp2_hi_i =
+ static_cast<int64_t>(static_cast<uint64_t>((hm_i >> 6) + FPBits::EXP_BIAS)
+ << FPBits::FRACTION_LEN);
+ double exp2_hi = FPBits(static_cast<uint64_t>(exp2_hi_i)).get_val();
+
+ // 2^mid
+ DoubleDouble exp2_mid{EXP2_MID1[idx_y].mid * sign_d,
+ EXP2_MID1[idx_y].hi * sign_d};
+
+ // Polynomial expansion for 2^(lo6/64):
+ // 2^(lo6/64) ~ 1 + lo6 * (log(2)/64) + lo6^2 * P(lo6)
+ // The linear term is computed in DoubleDouble, and the degree-3 polynomial
+ // P(lo6) is evaluated with standard double precision.
+ //
+ // hi and lo parts of log(2)/64, generated by Sollya with:
+ // > a = D(log(2)/64);
+ // > b = D(log(2)/64 - a);
+ constexpr DoubleDouble LOG_2_OVER_64 = {0x1.abc9e3b39803fp-62,
+ 0x1.62e42fefa39efp-7};
+
+ // Degree-3 polynomial approximation for (2^(lo6/64) - 1 - lo6*log(2)/64) /
+ // lo6^2: Generated by Sollya with:
+ // > f = (2^(x/64) - 1 - x*log(2)/64) / x^2;
+ // > P = fpminimax(f, 3, [|D...|], [-0.5, 0.5]);
+ // > dirtyinfnorm((f - P) * x^2, [-0.5, 0.5]);
+ // 0x1.439a...p-58
+ constexpr double EXP2_COEFFS[] = {
+ 0x1.ebfbdff82bb76p-15, 0x1.c6b08d704acbep-23, 0x1.3b2acb2c56647p-31,
+ 0x1.5d8803cdafb8ep-40};
+
+ DoubleDouble lo_log_2 = fputil::quick_mult(lo6, LOG_2_OVER_64);
+ DoubleDouble lo_log_2_p1 = fputil::exact_add(1.0, lo_log_2.hi);
+ lo_log_2_p1.lo += lo_log_2.lo;
+
+ double lo6_sq = lo6.hi * lo6.hi;
+ double e0 = fputil::multiply_add(lo6.hi, EXP2_COEFFS[1], EXP2_COEFFS[0]);
+ double e1 = fputil::multiply_add(lo6.hi, EXP2_COEFFS[3], EXP2_COEFFS[2]);
+ double pp = fputil::multiply_add(lo6_sq, e1, e0);
+
+ lo_log_2_p1.lo = fputil::multiply_add(lo6_sq, pp, lo_log_2_p1.lo);
+ DoubleDouble r = fputil::quick_mult(exp2_mid, lo_log_2_p1);
+
+ double tmp1 = (r.hi + r.lo) * exp2_hi;
+ return tmp1 * scale;
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_POW_FAST_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_utils.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_utils.h
new file mode 100644
index 00000000000..83eba6007e2
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/pow_utils.h
@@ -0,0 +1,661 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Common utilities and tables for double-precision pow(x, y).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POW_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_POW_UTILS_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/common_constants.h"
+#include "src/__support/math/exp10.h"
+#include "src/__support/math/exp2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace pow_internal {
+
+using fputil::DoubleDouble;
+using namespace common_constants_internal;
+
+// Constants for log2(x) range reduction, generated by Sollya with:
+// > for i from 0 to 127 do {
+// r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^-7) );
+// b = nearestint(log2(r) * 2^41) * 2^-41;
+// c = round(log2(r) - b, D, RN);
+// print("{ ", -c, ", ", -b, " }, ");
+// };
+// This is the same as -log2(RD[i]), with the least significant bits of the
+// high part set to be 2^-41, so that the sum of high parts + e_x is exact in
+// double precision.
+// We also replace the first and the last ones to be 0.
+LIBC_INLINE_VAR constexpr DoubleDouble LOG2_R_DD[128] = {
+ {0.0, 0.0},
+ {-0x1.19b14945cf6bap-44, 0x1.72c7ba21p-7},
+ {-0x1.95539356f93dcp-43, 0x1.743ee862p-6},
+ {0x1.abe0a48f83604p-43, 0x1.184b8e4c5p-5},
+ {0x1.635577970e04p-43, 0x1.77394c9d9p-5},
+ {-0x1.401fbaaa67e3cp-45, 0x1.d6ebd1f2p-5},
+ {-0x1.5b1799ceaeb51p-43, 0x1.1bb32a6008p-4},
+ {0x1.7c407050799bfp-43, 0x1.4c560fe688p-4},
+ {0x1.da6339da288fcp-43, 0x1.7d60496cf8p-4},
+ {0x1.be4f6f22dbbadp-43, 0x1.960caf9ab8p-4},
+ {-0x1.c760bc9b188c4p-45, 0x1.c7b528b71p-4},
+ {0x1.164e932b2d51cp-44, 0x1.f9c95dc1dp-4},
+ {0x1.924ae921f7ecap-45, 0x1.097e38ce6p-3},
+ {-0x1.6d25a5b8a19b2p-44, 0x1.22dadc2ab4p-3},
+ {0x1.e50a1644ac794p-43, 0x1.3c6fb650ccp-3},
+ {0x1.f34baa74a7942p-43, 0x1.494f863b8cp-3},
+ {-0x1.8f7aac147fdc1p-46, 0x1.633a8bf438p-3},
+ {0x1.f84be19cb9578p-43, 0x1.7046031c78p-3},
+ {-0x1.66cccab240e9p-46, 0x1.8a8980abfcp-3},
+ {-0x1.3f7a55cd2af4cp-47, 0x1.97c1cb13c8p-3},
+ {0x1.3458cde69308cp-43, 0x1.b2602497d4p-3},
+ {-0x1.667f21fa8423fp-44, 0x1.bfc67a8p-3},
+ {0x1.d2fe4574e09b9p-47, 0x1.dac22d3e44p-3},
+ {0x1.367bde40c5e6dp-43, 0x1.e857d3d36p-3},
+ {0x1.d45da26510033p-46, 0x1.01d9bbcfa6p-2},
+ {-0x1.7204f55bbf90dp-44, 0x1.08bce0d96p-2},
+ {-0x1.d4f1b95e0ff45p-43, 0x1.169c05364p-2},
+ {0x1.c20d74c0211bfp-44, 0x1.1d982c9d52p-2},
+ {0x1.ad89a083e072ap-43, 0x1.249cd2b13cp-2},
+ {0x1.cd0cb4492f1bcp-43, 0x1.32bfee370ep-2},
+ {-0x1.2101a9685c779p-47, 0x1.39de8e155ap-2},
+ {0x1.9451cd394fe8dp-43, 0x1.4106017c3ep-2},
+ {0x1.661e393a16b95p-44, 0x1.4f6fbb2cecp-2},
+ {-0x1.c6d8d86531d56p-44, 0x1.56b22e6b58p-2},
+ {0x1.c1c885adb21d3p-43, 0x1.5dfdcf1eeap-2},
+ {0x1.3bb5921006679p-45, 0x1.6552b49986p-2},
+ {0x1.1d406db502403p-43, 0x1.6cb0f6865cp-2},
+ {0x1.55a63e278bad5p-43, 0x1.7b89f02cf2p-2},
+ {-0x1.66ae2a7ada553p-49, 0x1.8304d90c12p-2},
+ {-0x1.66cccab240e9p-45, 0x1.8a8980abfcp-2},
+ {-0x1.62404772a151dp-45, 0x1.921800924ep-2},
+ {0x1.ac9bca36fd02ep-44, 0x1.99b072a96cp-2},
+ {0x1.4bc302ffa76fbp-43, 0x1.a8ff97181p-2},
+ {0x1.01fea1ec47c71p-43, 0x1.b0b67f4f46p-2},
+ {-0x1.f20203b3186a6p-43, 0x1.b877c57b1cp-2},
+ {-0x1.2642415d47384p-45, 0x1.c043859e3p-2},
+ {-0x1.bc76a2753b99bp-50, 0x1.c819dc2d46p-2},
+ {-0x1.da93ae3a5f451p-43, 0x1.cffae611aep-2},
+ {-0x1.50e785694a8c6p-43, 0x1.d7e6c0abc4p-2},
+ {0x1.c56138c894641p-43, 0x1.dfdd89d586p-2},
+ {0x1.5669df6a2b592p-43, 0x1.e7df5fe538p-2},
+ {-0x1.ea92d9e0e8ac2p-48, 0x1.efec61b012p-2},
+ {0x1.a0331af2e6feap-43, 0x1.f804ae8d0cp-2},
+ {0x1.9518ce032f41dp-48, 0x1.0014332bep-1},
+ {-0x1.b3b3864c60011p-44, 0x1.042bd4b9a8p-1},
+ {-0x1.103e8f00d41c8p-45, 0x1.08494c66b9p-1},
+ {0x1.65be75cc3da17p-43, 0x1.0c6caaf0c5p-1},
+ {0x1.3676289cd3dd4p-43, 0x1.1096015deep-1},
+ {-0x1.41dfc7d7c3321p-43, 0x1.14c560fe69p-1},
+ {0x1.e0cda8bd74461p-44, 0x1.18fadb6e2dp-1},
+ {0x1.2a606046ad444p-44, 0x1.1d368296b5p-1},
+ {0x1.f9ea977a639cp-43, 0x1.217868b0c3p-1},
+ {-0x1.50520a377c7ecp-45, 0x1.25c0a0463cp-1},
+ {0x1.6e3cb71b554e7p-47, 0x1.2a0f3c3407p-1},
+ {-0x1.4275f1035e5e8p-48, 0x1.2e644fac05p-1},
+ {-0x1.4275f1035e5e8p-48, 0x1.2e644fac05p-1},
+ {-0x1.979a5db68721dp-45, 0x1.32bfee370fp-1},
+ {0x1.1ee969a95f529p-43, 0x1.37222bb707p-1},
+ {0x1.bb4b69336b66ep-43, 0x1.3b8b1c68fap-1},
+ {0x1.d5e6a8a4fb059p-45, 0x1.3ffad4e74fp-1},
+ {0x1.3106e404cabb7p-44, 0x1.44716a2c08p-1},
+ {0x1.3106e404cabb7p-44, 0x1.44716a2c08p-1},
+ {-0x1.9bcaf1aa4168ap-43, 0x1.48eef19318p-1},
+ {0x1.1646b761c48dep-44, 0x1.4d7380dcc4p-1},
+ {0x1.2f0c0bfe9dbecp-43, 0x1.51ff2e3021p-1},
+ {0x1.29904613e33cp-43, 0x1.5692101d9bp-1},
+ {0x1.1d406db502403p-44, 0x1.5b2c3da197p-1},
+ {0x1.1d406db502403p-44, 0x1.5b2c3da197p-1},
+ {-0x1.125d6cbcd1095p-44, 0x1.5fcdce2728p-1},
+ {-0x1.bd9b32266d92cp-43, 0x1.6476d98adap-1},
+ {0x1.54243b21709cep-44, 0x1.6927781d93p-1},
+ {0x1.54243b21709cep-44, 0x1.6927781d93p-1},
+ {-0x1.ce60916e52e91p-44, 0x1.6ddfc2a79p-1},
+ {0x1.f1f5ae718f241p-43, 0x1.729fd26b7p-1},
+ {-0x1.6eb9612e0b4f3p-43, 0x1.7767c12968p-1},
+ {-0x1.6eb9612e0b4f3p-43, 0x1.7767c12968p-1},
+ {0x1.fed21f9cb2cc5p-43, 0x1.7c37a9227ep-1},
+ {0x1.7f5dc57266758p-43, 0x1.810fa51bf6p-1},
+ {0x1.7f5dc57266758p-43, 0x1.810fa51bf6p-1},
+ {0x1.5b338360c2ae2p-43, 0x1.85efd062c6p-1},
+ {-0x1.96fc8f4b56502p-43, 0x1.8ad846cf37p-1},
+ {-0x1.96fc8f4b56502p-43, 0x1.8ad846cf37p-1},
+ {-0x1.bdc81c4db3134p-44, 0x1.8fc924c89bp-1},
+ {0x1.36c101ee1344p-43, 0x1.94c287492cp-1},
+ {0x1.36c101ee1344p-43, 0x1.94c287492cp-1},
+ {0x1.e41fa0a62e6aep-44, 0x1.99c48be206p-1},
+ {-0x1.d97ee9124773bp-46, 0x1.9ecf50bf44p-1},
+ {-0x1.d97ee9124773bp-46, 0x1.9ecf50bf44p-1},
+ {-0x1.3f94e00e7d6bcp-46, 0x1.a3e2f4ac44p-1},
+ {-0x1.6879fa00b120ap-43, 0x1.a8ff971811p-1},
+ {-0x1.6879fa00b120ap-43, 0x1.a8ff971811p-1},
+ {0x1.1659d8e2d7d38p-44, 0x1.ae255819fp-1},
+ {0x1.1e5e0ae0d3f8ap-43, 0x1.b35458761dp-1},
+ {0x1.1e5e0ae0d3f8ap-43, 0x1.b35458761dp-1},
+ {0x1.484a15babcf88p-43, 0x1.b88cb9a2abp-1},
+ {0x1.484a15babcf88p-43, 0x1.b88cb9a2abp-1},
+ {0x1.871a7610e40bdp-45, 0x1.bdce9dcc96p-1},
+ {-0x1.2d90e5edaeceep-43, 0x1.c31a27dd01p-1},
+ {-0x1.2d90e5edaeceep-43, 0x1.c31a27dd01p-1},
+ {-0x1.5dd31d962d373p-43, 0x1.c86f7b7ea5p-1},
+ {-0x1.5dd31d962d373p-43, 0x1.c86f7b7ea5p-1},
+ {-0x1.9ad57391924a7p-43, 0x1.cdcebd2374p-1},
+ {-0x1.3167ccc538261p-44, 0x1.d338120a6ep-1},
+ {-0x1.3167ccc538261p-44, 0x1.d338120a6ep-1},
+ {0x1.c7a4ff65ddbc9p-45, 0x1.d8aba045bp-1},
+ {0x1.c7a4ff65ddbc9p-45, 0x1.d8aba045bp-1},
+ {-0x1.f9ab3cf74babap-44, 0x1.de298ec0bbp-1},
+ {-0x1.f9ab3cf74babap-44, 0x1.de298ec0bbp-1},
+ {0x1.52842c1c1e586p-43, 0x1.e3b20546f5p-1},
+ {0x1.52842c1c1e586p-43, 0x1.e3b20546f5p-1},
+ {0x1.3c6764fc87b4ap-48, 0x1.e9452c8a71p-1},
+ {0x1.3c6764fc87b4ap-48, 0x1.e9452c8a71p-1},
+ {-0x1.a0976c0a2827dp-44, 0x1.eee32e2aedp-1},
+ {-0x1.a0976c0a2827dp-44, 0x1.eee32e2aedp-1},
+ {-0x1.a45314dc4fc42p-43, 0x1.f48c34bd1fp-1},
+ {-0x1.a45314dc4fc42p-43, 0x1.f48c34bd1fp-1},
+ {0x1.ef5d00e390ap-44, 0x1.fa406bd244p-1},
+ {0.0, 1.0},
+};
+
+// Check if x is an odd integer: the lowest set bit must be at the unit
+// position:
+// x_e + lsb == UNIT_EXPONENT.
+LIBC_INLINE bool is_odd_integer(double x) {
+ using FPBits = fputil::FPBits<double>;
+ FPBits xbits(x);
+ uint64_t x_u = xbits.uintval();
+ unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
+ unsigned lsb =
+ static_cast<unsigned>(cpp::countr_zero(x_u | FPBits::EXP_MASK));
+ constexpr unsigned UNIT_EXPONENT =
+ static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
+ return (x_e + lsb == UNIT_EXPONENT);
+}
+
+// Check if x is an integer: the lowest set bit must be at or above the unit
+// position:
+// x_e + lsb >= UNIT_EXPONENT.
+LIBC_INLINE bool is_integer(double x) {
+ if (x == 0.0)
+ return true;
+ using FPBits = fputil::FPBits<double>;
+ FPBits xbits(x);
+ uint64_t x_u = xbits.uintval();
+ unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
+ unsigned lsb =
+ static_cast<unsigned>(cpp::countr_zero(x_u | FPBits::EXP_MASK));
+ constexpr unsigned UNIT_EXPONENT =
+ static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
+ return (x_e + lsb >= UNIT_EXPONENT);
+}
+
+LIBC_INLINE double set_overflow(bool is_neg) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_overflow_except_if_required<double>();
+ using FPBits = fputil::FPBits<double>;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_TOWARDZERO)
+ return is_neg ? -FPBits::max_normal().get_val()
+ : FPBits::max_normal().get_val();
+ if (rounding == FE_DOWNWARD)
+ return is_neg ? -FPBits::inf().get_val() : FPBits::max_normal().get_val();
+ if (rounding == FE_UPWARD)
+ return is_neg ? -FPBits::max_normal().get_val() : FPBits::inf().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return is_neg ? -FPBits::inf().get_val() : FPBits::inf().get_val();
+}
+
+LIBC_INLINE double set_underflow(bool is_neg) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_underflow_except_if_required<double>();
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ using FPBits = fputil::FPBits<double>;
+ int rounding = fputil::quick_get_round();
+ if (rounding == FE_UPWARD && !is_neg)
+ return FPBits::min_subnormal().get_val();
+ if (rounding == FE_DOWNWARD && is_neg)
+ return -FPBits::min_subnormal().get_val();
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return is_neg ? -0.0 : 0.0;
+}
+
+// Rounding tests for 2^hi * (mid + lo) when the output might be denormal. We
+// assume further that
+// 1 <= mid < 2,
+// mid + lo < 2,
+// and |lo| << mid.
+//
+// Notice that, if 0 < x < 2^-1022:
+// double( 2^-1022 + x ) - 2^-1022 = double(x),
+// and if -2^-1022 < x < 0:
+// double(-2^-1022 + x ) - -2^-1022 = double(x).
+//
+// So if we scale |x| up by 2^1022, we can use the "+1 trick" (or "-1 trick"
+// when x < 0):
+// double( 1.0 + 2^1022 * x) - 1.0, for x > 0, and
+// double(-1.0 + 2^1022 * x) - -1.0, for x < 0,
+// to test how x is rounded in the denormal range. By adding +-1.0, the
+// results will have similar rounding points as denormal outputs, aligning the
+// least significant bit of the mantissa with 2^-52 * 2^-1022 = 2^-1074.
+//
+// Finally, subtracting 1023 in the exponent field converts the rounded normal
+// value into the subnormal value.
+template <bool SKIP_ZIV_TEST = false>
+LIBC_INLINE constexpr cpp::optional<double>
+ziv_test_denorm(int hi, double mid, double lo, double err, bool is_neg) {
+ using FPBits = typename fputil::FPBits<double>;
+
+ uint64_t scale_u = static_cast<uint64_t>(hi + 2045) << FPBits::FRACTION_LEN;
+ double exp_scale = cpp::bit_cast<double>(scale_u);
+
+ double mid_hi = mid * exp_scale;
+ double lo_scaled = lo * exp_scale;
+
+ double extra_factor = 0.0;
+ uint64_t scale_down = 0x3FE0'0000'0000'0000ULL; // 1022 in the exponent field.
+
+ // Result is denormal if |mid_hi + lo_scaled| < 1.0.
+ // In that case, add +-1.0 to mimic denormal rounding points.
+ if (is_neg) {
+ if ((-1.0 - mid_hi) < lo_scaled) {
+ // Extra rounding step is needed, which adds more rounding errors.
+ extra_factor = -1.0;
+ scale_down = 0x3FF0'0000'0000'0000ULL; // 1023 in the exponent field.
+ err += 0x1.0p-52;
+ }
+ } else {
+ if ((1.0 - mid_hi) > lo_scaled) {
+ // Extra rounding step is needed, which adds more rounding errors.
+ extra_factor = 1.0;
+ scale_down = 0x3FF0'0000'0000'0000ULL; // 1023 in the exponent field.
+ err += 0x1.0p-52;
+ }
+ }
+
+ // By adding +-1.0, the hardware adder performs rounding at the exact same
+ // bit position as denormal rounding.
+ if constexpr (SKIP_ZIV_TEST) {
+ double r = extra_factor + (mid_hi + lo_scaled);
+ return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(r) - scale_down);
+ } else {
+ double err_scaled = err * exp_scale;
+
+ double lo_u = lo_scaled + err_scaled;
+ double lo_l = lo_scaled - err_scaled;
+
+ double upper = extra_factor + (mid_hi + lo_u);
+ double lower = extra_factor + (mid_hi + lo_l);
+
+ if (LIBC_LIKELY(upper == lower)) {
+ return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(upper) - scale_down);
+ }
+
+ return cpp::nullopt;
+ }
+}
+
+// Upper bound for y = 1075 / |log2(1 - 2^(-53)|, generated by Sollya:
+// > y = round(-1075 / log2(1 - 2^(-53)), D, RU);
+// > y;
+// 0x1.74910d52d3052p62
+// > printdouble(y);
+// 0x43d74910d52d3052
+constexpr uint64_t Y_UPPER_BOUND = 0x43d7'4910'd52d'3052;
+// Lower bound for y = 2^(-54) / 1074), generated by Sollya:
+// > y = round(2^(-54) / 1074), D, RD);
+// > y;
+// 0x1.e829f39aef509p-65
+// > printdouble(y);
+// 0x3bee829f39ae'f509
+constexpr uint64_t Y_LOWER_BOUND = 0x3bee'829f'39ae'f509;
+
+// Fast checks for special inputs:
+// x = 0, +-1, 2^k, 10, +- inf
+// y = 0, +-1, 2, 0.5
+LIBC_ALWAYS_INLINE cpp::optional<double> check_special_inputs(double x,
+ double y) {
+ using FPBits = fputil::FPBits<double>;
+ FPBits xbits(x), ybits(y);
+
+ bool x_sign = xbits.sign() == Sign::NEG;
+ bool y_sign = ybits.sign() == Sign::NEG;
+
+ FPBits x_abs = xbits.abs();
+ FPBits y_abs = ybits.abs();
+
+ uint64_t x_u = xbits.uintval();
+ uint64_t y_u = ybits.uintval();
+ uint64_t y_a = y_abs.uintval();
+
+ if (LIBC_UNLIKELY((x_u & 0x0003'FFFF'FFFF'FFFF) == 0) ||
+ ((y_u & 0x000F'FFFF'FFFF'FFFF) == 0)) {
+ // If x or y is signaling NaN
+ if (x_abs.is_signaling_nan() || y_abs.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ if (x == 1.0 || y == 0.0)
+ return 1.0;
+
+ if (x == 0.0) {
+ if (y_abs.is_nan())
+ return y;
+ if (y_abs.is_inf())
+ return y_sign ? FPBits::inf().get_val() : 0.0;
+ bool out_is_neg = x_sign && is_odd_integer(y);
+ if (y_sign) {
+ // pow(0, negative number) = inf
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ return FPBits::inf(out_is_neg ? Sign::NEG : Sign::POS).get_val();
+ }
+ // pow(0, positive number) = 0
+ return out_is_neg ? -0.0 : 0.0;
+ }
+
+ if (y == 1.0)
+ return x;
+
+ if (y == 2.0)
+ return x * x;
+
+ if (y == 0.5 && !x_sign)
+ return fputil::sqrt<double>(x);
+
+ // TODO: Add special case y = -0.5 when rsqrt is available.
+
+ if (x == 2.0)
+ return math::exp2(y);
+
+ if (x == 10.0)
+ return math::exp10(y);
+
+ // For x = 2^(+- 2^n):
+ // x^y = 2^(+- 2^n * y).
+ if (!x_sign && x_abs.is_normal() && xbits.get_mantissa() == 0 &&
+ y_a > Y_LOWER_BOUND && y_a < Y_UPPER_BOUND) {
+ int e_x = xbits.get_exponent();
+ uint32_t abs_e = static_cast<uint32_t>(e_x > 0 ? e_x : -e_x);
+ if (cpp::has_single_bit(abs_e)) {
+ double hi = static_cast<double>(e_x) * y;
+ if (hi >= 1024.0)
+ return set_overflow(false);
+ if (hi < -1075.0)
+ return set_underflow(false);
+ if (hi >= -1022.0)
+ return math::exp2(hi);
+ }
+ }
+ }
+
+ return cpp::nullopt;
+}
+
+// Filters out extreme input ranges, infinities, NaNs, normalizes denormal
+// inputs, and handles negative bases. Returns a value if the result is
+// determined, or nullopt if regular evaluation should proceed (in which case x,
+// y, e_x, x_mant, is_neg, sign_d may be updated).
+LIBC_ALWAYS_INLINE cpp::optional<double>
+check_exceptional_cases(double &x, double &y, double &e_x, uint64_t &x_mant,
+ bool &is_neg, double &sign_d) {
+ using FPBits = fputil::FPBits<double>;
+
+ FPBits xbits(x), ybits(y);
+ bool x_sign = xbits.sign() == Sign::NEG;
+ bool y_sign = ybits.sign() == Sign::NEG;
+
+ FPBits x_abs = xbits.abs();
+ FPBits y_abs = ybits.abs();
+
+ uint64_t x_u = xbits.uintval();
+ uint64_t y_mant = ybits.get_mantissa();
+ uint64_t x_a = x_abs.uintval();
+ uint64_t y_a = y_abs.uintval();
+
+ if (LIBC_UNLIKELY(y_a <= Y_LOWER_BOUND || y_a >= Y_UPPER_BOUND ||
+ x_u >= FPBits::inf().uintval() ||
+ x_u < FPBits::min_normal().uintval())) {
+ // If x or y is signaling NaN
+ if (x_abs.is_signaling_nan() || y_abs.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // |y| > |1075 / log2(1 - 2^-53)|.
+ if (y_a > 0x43d7'4910'd52d'3052) {
+ if (y_a >= 0x7ff0'0000'0000'0000) {
+ // y is inf or nan
+ if (y_mant != 0) {
+ // y is NaN
+ // pow(1, NaN) = 1 is already dealt with.
+ // pow(x, NaN) = NaN
+ return y;
+ }
+
+ // Now y is +-Inf
+ if (x_abs.is_nan()) {
+ // pow(NaN, +-Inf) = NaN
+ return x;
+ }
+
+ if (x_a == 0x3ff0'0000'0000'0000) {
+ // pow(+-1, +-Inf) = 1.0
+ return 1.0;
+ }
+
+ // pow (|x| < 1, -inf) = +inf
+ // pow (|x| < 1, +inf) = 0.0
+ // pow (|x| > 1, -inf) = 0.0
+ // pow (|x| > 1, +inf) = +inf
+ return ((x_a < FPBits::one().uintval()) == y_sign)
+ ? FPBits::inf().get_val()
+ : 0.0;
+ }
+ // x^y will overflow / underflow in double precision. Set y to a
+ // large enough exponent but not too large, so that the computations
+ // won't overflow in double precision.
+ y = y_sign ? -0x1.0p100 : 0x1.0p100;
+ }
+
+ // y is finite and non-zero.
+
+ if (x_a == FPBits::inf().uintval()) {
+ bool out_is_neg = x_sign && is_odd_integer(y);
+ Sign out_sign = out_is_neg ? Sign::NEG : Sign::POS;
+ return y_sign ? FPBits::zero(out_sign).get_val()
+ : FPBits::inf(out_sign).get_val();
+ }
+
+ if (x_a > FPBits::inf().uintval()) {
+ // x is NaN.
+ // pow (aNaN, 0) is already taken care above.
+ return x;
+ }
+
+ // Normalize denormal inputs.
+ if (x_a < FPBits::min_normal().uintval()) {
+ FPBits x_norm(x * 0x1.0p64);
+ e_x = static_cast<double>(x_norm.get_exponent()) - 64.0;
+ x_mant = x_norm.get_mantissa();
+ }
+
+ // x is finite and negative, and y is a finite integer.
+ if (x_sign) {
+ if (is_integer(y)) {
+ x = -x;
+ if (is_odd_integer(y)) {
+ is_neg = true;
+ sign_d = -1.0;
+ }
+ } else {
+ // pow( negative, non-integer ) = NaN
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ }
+
+ if (y_a <= Y_LOWER_BOUND) {
+ volatile double one = 1.0;
+ volatile double eps = ((x_a < FPBits::one().uintval()) == !y_sign)
+ ? -0x1.0p-100
+ : 0x1.0p-100;
+ return one + eps;
+ }
+ }
+
+ return cpp::nullopt;
+}
+
+// Check if x^y is an exact rounding boundary case (a 54-bit dyadic float,
+// which is either an exact 53-bit float or an exact halfway midpoint).
+//
+// Reference:
+// Lauter, C. and Lefevre, V., "Rounding Boundary Cases for Values of the
+// Exponential and Power Functions," IEEE Trans. Comput. 58(8):1063-1074.
+//
+// For a normalized 128-bit dyadic float with MSB at bit 127, the top 54 bits
+// occupy bits [127:74]. For any 54-bit number, bits [73:0] are zero.
+//
+// If x^y is not in F_54:
+// |x^y - o_54(x^y)| / x^y >= 2^-114.
+// With an evaluation error < 2^-115, the distance from bits [73:0] to the
+// nearest 54-bit boundary must satisfy:
+// dist >= (2^-114 - 2^-115) * 2^127 = 2^12.
+// We use a threshold of 2^-114 (dist < 2^13) to capture all boundary
+// candidates:
+//
+// 1. x = 2^e: x^y = 2^(e * y) is in F_54 iff e * y is an integer.
+// 2. x = m * 2^e, y = n * 2^f with m, n odd integers:
+// x^y in F_54 implies:
+// - 0 <= y <= 35, n <= 35, and f >= -5.
+// - e * y is an integer.
+// - When f < 0 (i.e. y = n / 2^(-f)): m^(2^f) is an integer, verified
+// by taking repeated square roots -f times.
+// - The resulting significand (m^(2^f))^n <= 2^54.
+//
+// Returns true and sets exact_m and exact_exp if x^y is an exact boundary.
+LIBC_INLINE bool is_exact_rounding_boundary(double x, double y,
+ uint64_t &exact_m, int &exact_exp) {
+ using FPBits = fputil::FPBits<double>;
+
+ FPBits xbits(x);
+ int x_e = 0;
+ uint64_t x_mant = xbits.get_mantissa();
+ if (LIBC_UNLIKELY(xbits.get_biased_exponent() == 0)) {
+ if (x_mant != 0) {
+ int shift = cpp::countl_zero(x_mant) - 11;
+ x_mant = (x_mant << shift) & FPBits::FRACTION_MASK;
+ x_e = -1022 - shift;
+ }
+ } else {
+ x_e = xbits.get_exponent();
+ }
+
+ // Case 1: x = 2^e.
+ if (x_mant == 0) {
+ double e = static_cast<double>(x_e);
+ double ey = e * y;
+ if (is_integer(ey)) {
+ exact_m = 1;
+ exact_exp = static_cast<int>(ey);
+ return true;
+ }
+ return false;
+ }
+
+ // Case 2: x is not a power of 2.
+ if (y < 0.0 || y > 35.0)
+ return false;
+
+ // Decompose y = n * 2^f with n odd.
+ FPBits ybits(y);
+ uint64_t y_mant = ybits.get_mantissa() | (1ULL << FPBits::FRACTION_LEN);
+ int y_exp = ybits.get_exponent() - static_cast<int>(FPBits::FRACTION_LEN);
+ int tz_y = cpp::countr_zero(y_mant);
+ uint64_t n = y_mant >> tz_y;
+ int f = y_exp + tz_y;
+
+ if (n > 35 || f < -5)
+ return false;
+
+ // Decompose x = m * 2^e with m odd.
+ uint64_t full_x_mant = x_mant | (1ULL << FPBits::FRACTION_LEN);
+ int tz_x = cpp::countr_zero(full_x_mant);
+ uint64_t m = full_x_mant >> tz_x;
+ int e = x_e - static_cast<int>(FPBits::FRACTION_LEN) + tz_x;
+
+ if (f < 0) {
+ // Non-integer exponent: y = n / 2^(-f) with -f in {1, ..., 5}.
+ double ey = static_cast<double>(e) * y;
+ if (!is_integer(ey))
+ return false;
+
+ // Check if m^(2^f) is an integer by taking repeated square roots -f times.
+ int count = -f;
+ uint64_t cur = m;
+ for (int i = 0; i < count; ++i) {
+ uint64_t s =
+ static_cast<uint64_t>(fputil::sqrt<double>(static_cast<double>(cur)));
+ if (s * s != cur)
+ return false;
+ cur = s;
+ }
+
+ // Compute res = cur^n and ensure res <= 2^54.
+ uint64_t res = 1;
+ for (uint64_t i = 0; i < n; ++i) {
+ if (res > (1ULL << 54) / cur)
+ return false;
+ res *= cur;
+ }
+ exact_m = res;
+ exact_exp = static_cast<int>(ey);
+ return true;
+ } else {
+ // Integer exponent: f >= 0, so y is an integer.
+ int y_int = static_cast<int>(y);
+ uint64_t res = 1;
+ for (int i = 0; i < y_int; ++i) {
+ if (res > (1ULL << 54) / m)
+ return false;
+ res *= m;
+ }
+ exact_m = res;
+ exact_exp = e * y_int;
+ return true;
+ }
+}
+
+} // namespace pow_internal
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_POW_UTILS_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/powf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/powf.h
index 7721d0d7f95..944b477ac44 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/powf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/powf.h
@@ -1,10 +1,15 @@
-//===-- Implementation header for powf --------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for powf.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_POWF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_POWF_H
@@ -25,6 +30,7 @@
#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS && LIBC_MATH_HAS_SMALL_TABLES
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -979,9 +985,8 @@ LIBC_INLINE float powf(float x, float y) {
// Clamp the exponent part into smaller range that fits double precision.
// For those exponents that are out of range, the final conversion will round
// them correctly to inf/max float or 0/min float accordingly.
- int64_t hm_i = static_cast<int64_t>(hm);
- hm_i = (hm_i > (1 << 15)) ? (1 << 15)
- : (hm_i < (-(1 << 15)) ? -(1 << 15) : hm_i);
+ int64_t hm_i =
+ cpp::clamp<int64_t>(static_cast<int64_t>(hm), -(1 << 15), 1 << 15);
int idx_y = hm_i & 0x3f;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/round.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/round.h
index d35c9f437a6..1f0d0189579 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/round.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/round.h
@@ -12,6 +12,8 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/architectures.h"
#include "src/__support/macros/properties/compiler.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -38,12 +40,20 @@ namespace math {
// still generate callback for ARM version < 8, and for x86-64 with
// `-ffp-model=strict`.
+// Notes: `__builtin_round` expansion for x86-64 using SSE4.1 rounding
+// instruction by clang is only correct for the default rounding mode.
+// See https://github.com/llvm/llvm-project/issues/140252
+// So we will only use `__builtin_round` with clang on x86-64 if we assume
+// default rounding mode (FE_TONEAREST) only.
+
LIBC_INLINE LIBC_CONSTEXPR double round(double x) {
#if __has_builtin(__builtin_round) && !defined(LIBC_USE_CONSTEXPR) && \
(defined(__LIBC_USE_BUILTIN_ROUND) || \
(defined(LIBC_COMPILER_IS_CLANG) && \
defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) && \
- (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8))))
+ (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8)) && \
+ (!defined(LIBC_TARGET_ARCH_IS_X86) || \
+ defined(LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY))))
return __builtin_round(x);
#else
return fputil::round(x);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf.h
index 5abe9ebad15..e1cb4fc9c2e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf.h
@@ -12,6 +12,8 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/architectures.h"
#include "src/__support/macros/properties/compiler.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -38,12 +40,20 @@ namespace math {
// still generate callback for ARM version < 8, and for x86-64 with
// `-ffp-model=strict`.
+// Notes: `__builtin_roundf` expansion for x86-64 using SSE4.1 rounding
+// instruction by clang is only correct for the default rounding mode.
+// See https://github.com/llvm/llvm-project/issues/140252
+// So we will only use `__builtin_round` with clang on x86-64 if we assume
+// default rounding mode (FE_TONEAREST) only.
+
LIBC_INLINE LIBC_CONSTEXPR float roundf(float x) {
#if __has_builtin(__builtin_roundf) && !defined(LIBC_USE_CONSTEXPR) && \
(defined(__LIBC_USE_BUILTIN_ROUND) || \
(defined(LIBC_COMPILER_IS_CLANG) && \
defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT) && \
- (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8))))
+ (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8)) && \
+ (!defined(LIBC_TARGET_ARCH_IS_X86) || \
+ defined(LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY))))
return __builtin_roundf(x);
#else
return fputil::round(x);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsig.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsig.h
index 2c19ceadfae..460ff8ab37d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsig.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsig.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsig(double *res, double pl) {
+LIBC_INLINE constexpr int setpayloadsig(double *res, double pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigbf16.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigbf16.h
index 58bf078e7e3..21f0e987920 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigbf16.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigbf16.h
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsigbf16(bfloat16 *res, bfloat16 pl) {
+LIBC_INLINE constexpr int setpayloadsigbf16(bfloat16 *res, bfloat16 pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf.h
index 95a0540eb44..7d8b57255ff 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsigf(float *res, float pl) {
+LIBC_INLINE constexpr int setpayloadsigf(float *res, float pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf128.h
index 6a519209111..c9bd9498cfb 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf128.h
@@ -20,7 +20,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsigf128(float128 *res, float128 pl) {
+LIBC_INLINE constexpr int setpayloadsigf128(float128 *res, float128 pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf16.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf16.h
index e3629cfe3d0..92443d4b091 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf16.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigf16.h
@@ -20,7 +20,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsigf16(float16 *res, float16 pl) {
+LIBC_INLINE constexpr int setpayloadsigf16(float16 *res, float16 pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigl.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigl.h
index 9b9de4109e0..7bbfa586b21 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigl.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadsigl.h
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE int setpayloadsigl(long double *res, long double pl) {
+LIBC_INLINE constexpr int setpayloadsigl(long double *res, long double pl) {
return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/sin.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/sin.h
index 0c8933c10fd..5038ed55fb0 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/sin.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/sin.h
@@ -1,10 +1,15 @@
-//===-- Implementation header for sin ---------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sin.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_SIN_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_SIN_H
@@ -127,8 +132,8 @@ LIBC_INLINE double sin(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
return x + r_lo;
#else
- // Overall errors <= 2 * ulp(x^3/6) + |x| * 2^-68.
- double err = fputil::multiply_add(x_sq, 0x1.0p-53, 0x1.0p-68);
+ // Overall errors <= ulp(x^3) + |x| * 2^-68.
+ double err = fputil::multiply_add(x_sq, 0x1.0p-52, 0x1.0p-68);
double r_lo_u = fputil::multiply_add(x, err, r_lo);
double r_lo_l = fputil::multiply_add(-x, err, r_lo);
double r_upper = x + r_lo_u;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math_extras.h b/deps/v8/third_party/llvm-libc/src/src/__support/math_extras.h
index b8abf8041c8..8de5c50d0f1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math_extras.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math_extras.h
@@ -108,13 +108,17 @@ add_with_carry(T a, T b, T carry_in, T &carry_out) {
if (!cpp::is_constant_evaluated()) {
#if __has_builtin(__builtin_addcb)
RETURN_IF(unsigned char, __builtin_addcb)
-#elif __has_builtin(__builtin_addcs)
+#endif
+#if __has_builtin(__builtin_addcs)
RETURN_IF(unsigned short, __builtin_addcs)
-#elif __has_builtin(__builtin_addc)
+#endif
+#if __has_builtin(__builtin_addc)
RETURN_IF(unsigned int, __builtin_addc)
-#elif __has_builtin(__builtin_addcl)
+#endif
+#if __has_builtin(__builtin_addcl)
RETURN_IF(unsigned long, __builtin_addcl)
-#elif __has_builtin(__builtin_addcll)
+#endif
+#if __has_builtin(__builtin_addcll)
RETURN_IF(unsigned long long, __builtin_addcll)
#endif
}
@@ -134,13 +138,17 @@ sub_with_borrow(T a, T b, T carry_in, T &carry_out) {
if (!cpp::is_constant_evaluated()) {
#if __has_builtin(__builtin_subcb)
RETURN_IF(unsigned char, __builtin_subcb)
-#elif __has_builtin(__builtin_subcs)
+#endif
+#if __has_builtin(__builtin_subcs)
RETURN_IF(unsigned short, __builtin_subcs)
-#elif __has_builtin(__builtin_subc)
+#endif
+#if __has_builtin(__builtin_subc)
RETURN_IF(unsigned int, __builtin_subc)
-#elif __has_builtin(__builtin_subcl)
+#endif
+#if __has_builtin(__builtin_subcl)
RETURN_IF(unsigned long, __builtin_subcl)
-#elif __has_builtin(__builtin_subcll)
+#endif
+#if __has_builtin(__builtin_subcll)
RETURN_IF(unsigned long long, __builtin_subcll)
#endif
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/CMakeLists.txt
index 6e5f3bbddc1..431ad79f105 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/CMakeLists.txt
@@ -232,13 +232,26 @@ add_header_library(
libc.src.__support.math.rsqrtf
)
+add_header_library(
+ trig_reductionf
+ HDRS
+ trig_reductionf.h
+ trig_reductionf_nofma.h
+ DEPENDS
+ libc.src.__support.CPP.bit
+ libc.src.__support.CPP.simd
+)
+
add_header_library(
sinf
HDRS
sinf.h
DEPENDS
+ .trig_reductionf
+ libc.src.__support.CPP.bit
libc.src.__support.CPP.simd
- libc.src.__support.math.sinf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.properties.cpu_features
)
add_header_library(
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/sinf.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/sinf.h
index 7b2c15f8a72..e99356165f6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/sinf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/sinf.h
@@ -14,21 +14,89 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
+#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/simd.h"
-#define LIBC_MATH_HAS_NO_ERRNO
-#define LIBC_MATH_HAS_NO_EXCEPT
-#define LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
-#include "src/__support/math/sinf.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "src/__support/mathvec/trig_reductionf.h"
+#else
+#include "src/__support/mathvec/trig_reductionf_nofma.h"
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
namespace LIBC_NAMESPACE_DECL {
namespace mathvec {
template <size_t N>
-LIBC_INLINE cpp::simd<float, N> sinf(cpp::simd<float, N> x) {
- return cpp::map(x, [](float a) { return math::sinf(a); });
+LIBC_INLINE static cpp::simd<double, N> sinpif_poly(cpp::simd<double, N> r) {
+ // Approximate sin(pi * r) for |r| <= 0.5.
+ // These coefficients aren't produced directly via sollya, but rather
+ // are fine-tuned by iterative adjustment to remove hard to round cases.
+ // TODO: Create a tool to deterministically reproduce these coefficients.
+ // see https://github.com/llvm/llvm-project/issues/220984
+ constexpr cpp::simd<double, N> c0 = 0x1.921fb54442d15p1;
+ constexpr cpp::simd<double, N> c1 = -0x1.4abbce625bcbdp2;
+ constexpr cpp::simd<double, N> c2 = 0x1.466bc67749fe8p1;
+ constexpr cpp::simd<double, N> c3 = -0x1.32d2ccde52aaap-1;
+ constexpr cpp::simd<double, N> c4 = 0x1.5078311af79bdp-4;
+ constexpr cpp::simd<double, N> c5 = -0x1.e305b6b7642fbp-8;
+ constexpr cpp::simd<double, N> c6 = 0x1.e889fb0d0db0dp-12;
+ constexpr cpp::simd<double, N> c7 = -0x1.611a523a97eb1p-16;
+
+ cpp::simd<double, N> r2 = r * r;
+ cpp::simd<double, N> r4 = r2 * r2;
+ cpp::simd<double, N> p01 = cpp::multiply_add(r2, c1, c0);
+ cpp::simd<double, N> p23 = cpp::multiply_add(r2, c3, c2);
+ cpp::simd<double, N> p45 = cpp::multiply_add(r2, c5, c4);
+ cpp::simd<double, N> p67 = cpp::multiply_add(r2, c7, c6);
+ cpp::simd<double, N> p47 = cpp::multiply_add(r4, p67, p45);
+ cpp::simd<double, N> p27 = cpp::multiply_add(r4, p47, p23);
+ cpp::simd<double, N> p07 = cpp::multiply_add(r4, p27, p01);
+ return r * p07;
}
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sinf(cpp::simd<float, N> x) {
+ using FPBits = typename fputil::FPBits<float>;
+
+ cpp::simd<float, N> ax = cpp::abs(x);
+ cpp::simd<uint32_t, N> x_sign = cpp::bit_cast<cpp::simd<uint32_t>>(x) ^
+ cpp::bit_cast<cpp::simd<uint32_t>>(ax);
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ constexpr float large_reduction_bound = 0x1.6d28ce103p+52f;
+#else
+ constexpr float large_reduction_bound = 0x1.0p+51f;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ cpp::simd<bool, N> has_large_reduction = (ax > large_reduction_bound);
+
+ cpp::simd<double, N> x_d = cpp::simd_cast<double>(ax);
+ Reduction<N> reduce{};
+
+ // Values at or below the large bound can use a fast Cody-Waite reduction.
+ if (LIBC_LIKELY(!cpp::all_of(has_large_reduction)))
+ reduce = fast_reduction(x_d);
+
+ // Large inputs require a more involved reduction, as well as inf handling.
+ if (LIBC_UNLIKELY(cpp::any_of(has_large_reduction))) {
+ cpp::simd<bool, N> is_finite = ax < FPBits::inf().get_val();
+ Reduction<N> large_reduce = large_reduction(x_d);
+ reduce.r = has_large_reduction ? large_reduce.r : reduce.r;
+ reduce.odd = has_large_reduction ? large_reduce.odd : reduce.odd;
+ reduce.r = is_finite ? reduce.r : FPBits::quiet_nan().get_val();
+ }
+
+ // Both reduction paths feed into a single polynomial evaluation + sign
+ // correction.
+ cpp::simd<float, N> poly = cpp::simd_cast<float>(sinpif_poly(reduce.r));
+ cpp::simd<uint32_t, N> sign = cpp::simd_cast<uint32_t>(reduce.odd) << 31;
+
+ // XORing the sign correction with the input sign preserves -0.
+ sign ^= x_sign;
+ return cpp::bit_cast<cpp::simd<float>>(
+ cpp::bit_cast<cpp::simd<uint32_t>>(poly) ^ sign);
+}
} // namespace mathvec
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf.h
new file mode 100644
index 00000000000..dac25066834
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf.h
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains range reductions for single-precision trigonometric
+/// functions for targets with FMA support.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N> struct Reduction {
+ cpp::simd<double, N> r;
+ cpp::simd<int64_t, N> odd;
+};
+
+// Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE static Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> inv_pi = 0x1.45f306dc9c883p-2;
+ constexpr cpp::simd<double, N> inv_pi_tail = -0x1.6b01ec5417056p-56;
+ constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+ // Adding shift rounds x / pi to the nearest integer k,
+ // producing z = shift + k. Therefore t = shift - z = -k.
+ cpp::simd<double, N> z = cpp::multiply_add(x, inv_pi, shift);
+ cpp::simd<double, N> t = shift - z;
+
+ // r = x/pi - k
+ cpp::simd<double, N> r;
+ r = cpp::multiply_add(x, inv_pi, t);
+ r = cpp::multiply_add(x, inv_pi_tail, r);
+
+ return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(z)};
+}
+
+// Two-double expansions of 2^(8*q) / pi reduced modulo an even integer,
+// q = 3..12. Padded to a 16 length array for easier access.
+LIBC_INLINE_VAR constexpr double INV_PI_HI[16] = {
+ 0,
+ 0,
+ 0,
+ -0x1.236377d5ac07bp-2,
+ -0x1.b1bbead603d8bp-1,
+ -0x1.bbead603d8a83p-1,
+ 0x1.529fc2757d1f5p-5,
+ 0x1.29fc2757d1f53p-1,
+ 0x1.fc2757d1f534ep-1,
+ 0x1.3abe8fa9a6eep-4,
+ -0x1.505c1596447e5p-2,
+ -0x1.70565911f924fp-4,
+ 0x1.f534ddc0db629p-1,
+ 0,
+ 0,
+ 0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
+ 0,
+ 0,
+ 0,
+ -0x1.505c1596447e5p-58,
+ 0x1.f47d4d377036ep-55,
+ 0x1.f534ddc0db629p-57,
+ 0x1.a6ee06db14acdp-60,
+ 0x1.377036d8a5665p-55,
+ -0x1.1f924eb53361ep-56,
+ 0x1.b6c52b3278872p-58,
+ 0x1.b14acc9e21c82p-56,
+ 0x1.2b32788720840p-58,
+ 0x1.664f10e4107f9p-55,
+ 0,
+ 0,
+ 0,
+};
+
+// Reduces non-negative large finite inputs x >= 0x1p49.
+// Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE static Reduction<N> large_reduction(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+ cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);
+
+ // Compute q = floor((unbiased_exponent - 25) / 8).
+ // Since 1023 + 25 = 8 * 131, this can be calculated as (ix >> 55) - 131.
+ cpp::simd<int64_t, N> q =
+ cpp::simd_cast<int64_t>(ix >> 55) - cpp::simd<int64_t, N>(131);
+
+ // While sufficiently large x will always produce q within [3, 12],
+ // not all input lanes are guaranteed to require the large reduction,
+ // so we mask with 15 to keep all values within bounds.
+ cpp::simd<int64_t, N> idx = q & cpp::simd<int64_t, N>(15);
+ cpp::simd<double, N> c_hi =
+ cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_HI);
+ cpp::simd<double, N> c_lo =
+ cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_LO);
+
+ // xr = x * 2^(-8*q) is an integer with xr in [2^25, 2^33).
+ cpp::simd<uint64_t, N> scale = cpp::bit_cast<cpp::simd<uint64_t, N>>(q) << 55;
+ cpp::simd<double, N> xr = cpp::bit_cast<cpp::simd<double, N>>(ix - scale);
+
+ // Subtract the nearest integer from xr * c_hi, and add the tail.
+ cpp::simd<double, N> biased = cpp::multiply_add(xr, c_hi, shift);
+ cpp::simd<double, N> kd = biased - shift;
+ cpp::simd<double, N> r = cpp::multiply_add(xr, c_hi, -kd);
+ r = cpp::multiply_add(xr, c_lo, r);
+
+ return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(biased)};
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf_nofma.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf_nofma.h
new file mode 100644
index 00000000000..ac2f029922c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/trig_reductionf_nofma.h
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains range reductions for single-precision trigonometric
+/// functions for targets with no FMA support.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N> struct Reduction {
+ cpp::simd<double, N> r;
+ cpp::simd<int64_t, N> odd;
+};
+
+// Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE static Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> inv_pi_hi = 0x1.45f306e000000p-2;
+ constexpr cpp::simd<double, N> inv_pi_mid = -0x1.b1bbead000000p-33;
+ constexpr cpp::simd<double, N> inv_pi_lo = -0x1.80f62a0b82b00p-63;
+ constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+ // Since we know the input was cast to FP64 from FP32, we can use split
+ // 1 / pi coefficients such that the products of hi and mid are exact.
+ // The low part restores the remaining precision without requiring an FMA.
+ cpp::simd<double, N> x_hi = x * inv_pi_hi;
+ cpp::simd<double, N> x_mid = x * inv_pi_mid;
+ cpp::simd<double, N> x_lo = x * inv_pi_lo;
+
+ // Adding shift rounds x / pi to the nearest integer k, producing
+ // z = shift + k. Therefore t = shift - z = -k.
+ cpp::simd<double, N> z = shift + (x_hi + x_mid);
+ cpp::simd<double, N> t = shift - z;
+
+ // Accumulate the split products from largest to smallest to recover
+ // r = x / pi - k.
+ cpp::simd<double, N> r = t + x_hi + x_mid + x_lo;
+
+ // The low bit of z's representation encodes the parity of k.
+ return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(z)};
+}
+
+// Three-double expansions of 2^(8*q) / pi, reduced modulo an even integer,
+// q = 3..12. Padded to 16 length arrays for safe masked indexing.
+LIBC_INLINE_VAR constexpr double INV_PI_HI[16] = {
+ 0,
+ 0,
+ 0,
+ -0x1.236377d000000p-2,
+ -0x1.b1bbead000000p-1,
+ -0x1.bbead60000000p-1,
+ 0x1.529fc27000000p-5,
+ 0x1.29fc275000000p-1,
+ 0x1.fc2757d000000p-1,
+ 0x1.3abe8fb000000p-4,
+ -0x1.505c159000000p-2,
+ -0x1.7056591000000p-4,
+ 0x1.f534ddc000000p-1,
+ 0,
+ 0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_MID[16] = {
+ 0,
+ 0,
+ 0,
+ -0x1.6b01ec5000000p-32,
+ -0x1.80f62a1000000p-31,
+ -0x1.ec54170000000p-32,
+ 0x1.5f47d4d000000p-35,
+ 0x1.f47d4d3000000p-31,
+ 0x1.f534ddc000000p-33,
+ -0x1.96447e5000000p-34,
+ -0x1.911f925000000p-32,
+ -0x1.f924eb5000000p-36,
+ 0x1.b6c52b3000000p-34,
+ 0,
+ 0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
+ 0,
+ 0,
+ 0,
+ -0x1.05c1596447e50p-62,
+ 0x1.1f534ddc0db80p-61,
+ -0x1.596447e493ae0p-62,
+ 0x1.bb81b6c52b340p-66,
+ 0x1.dc0db62959940p-61,
+ 0x1.b6c52b3278800p-66,
+ 0x1.b14acc9e21c80p-64,
+ 0x1.4acc9e21c8200p-64,
+ -0x1.9b0ef1bef8000p-67,
+ 0x1.3c439041fe400p-65,
+ 0,
+ 0,
+};
+
+// Reduces non-negative large finite inputs x >= 0x1p49.
+// Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE static Reduction<N> large_reduction(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+ cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);
+
+ // Compute q = floor((unbiased_exponent - 25) / 8).
+ // Since 1023 + 25 = 8 * 131, this is (ix >> 55) - 131.
+ cpp::simd<int64_t, N> q =
+ cpp::simd_cast<int64_t>(ix >> 55) - cpp::simd<int64_t, N>(131);
+
+ // While sufficiently large x will always produce q within [3, 12],
+ // not all input lanes are guaranteed to require the large reduction,
+ // so we mask with 15 to keep all values within bounds.
+ cpp::simd<int64_t, N> idx = q & cpp::simd<int64_t, N>(15);
+ cpp::simd<double, N> c_hi =
+ cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_HI);
+ cpp::simd<double, N> c_mid =
+ cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_MID);
+ cpp::simd<double, N> c_lo =
+ cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_LO);
+
+ // xr = x * 2^(-8*q) is an integer with xr in [2^25, 2^33).
+ cpp::simd<uint64_t, N> scale = cpp::bit_cast<cpp::simd<uint64_t, N>>(q) << 55;
+ cpp::simd<double, N> xr = cpp::bit_cast<cpp::simd<double, N>>(ix - scale);
+
+ // Multiplication by the high and middle parts is exact because xr retains
+ // the 24-bit significand of its FP32 source and each coefficient has at
+ // most 29 significant bits. The low part supplies the remaining precision.
+ cpp::simd<double, N> x_hi = xr * c_hi;
+ cpp::simd<double, N> x_mid = xr * c_mid;
+ cpp::simd<double, N> x_lo = xr * c_lo;
+
+ // Add from largest to smallest before using shift to obtain the nearest
+ // integer k.
+ cpp::simd<double, N> x_sum = (x_hi + x_mid) + x_lo;
+ cpp::simd<double, N> biased = shift + x_sum;
+ cpp::simd<double, N> kd = biased - shift;
+
+ // Subtract k from the same split expansion to recover r = x / pi - k.
+ cpp::simd<double, N> r = x_hi - kd;
+ r = r + x_mid;
+ r = r + x_lo;
+
+ // The low bit of biased's representation encodes the parity of k.
+ return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(biased)};
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/net/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/net/CMakeLists.txt
index e243ed5c8a2..80b141d06cd 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/net/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/net/CMakeLists.txt
@@ -13,6 +13,7 @@ add_object_library(
libc.src.__support.ctype_utils
libc.src.__support.CPP.optional
libc.src.__support.CPP.span
+ libc.src.__support.CPP.string_view
libc.src.__support.libc_assert
libc.src.__support.str_to_integer
libc.src.string.memory_utils.inline_memcpy
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/net/address.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/net/address.cpp
index ce78249169d..8e0554ccc29 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/net/address.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/net/address.cpp
@@ -17,6 +17,7 @@
#include "hdr/types/in_addr_t.h"
#include "hdr/types/struct_in6_addr.h"
#include "hdr/types/struct_in_addr.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/endian_internal.h"
@@ -27,34 +28,36 @@
namespace LIBC_NAMESPACE_DECL {
namespace net {
-cpp::optional<in_addr_t> inet_addr(const char *cp) {
+cpp::optional<in_addr_t> inet_addr(cpp::string_view src) {
constexpr int IPV4_MAX_DOT_NUM = 3;
in_addr_t parts[IPV4_MAX_DOT_NUM + 1] = {0};
int dot_num = 0;
for (; dot_num <= IPV4_MAX_DOT_NUM; ++dot_num) {
- // strtointeger skips leading whitespace signs (1.+2.-3. 4), but we don't
- // want that, so we explicitly check that the first character is a digit.
- if (!internal::isdigit(*cp))
+ // strtointeger skips leading whitespace and signs, and accepts C23 binary
+ // string prefix (0b1.+2.-3. 4), but we don't want any of that, so we
+ // explicitly check reject these constructs.
+ if (src.empty() || !internal::isdigit(src[0]) || src.starts_with("0b") ||
+ src.starts_with("0B"))
return cpp::nullopt;
- auto result = internal::strtointeger<in_addr_t>(cp, 0);
+ auto result = internal::strtointeger<in_addr_t>(src.data(), 0, src.size());
parts[dot_num] = result;
if (result.has_error() || result.parsed_len == 0)
return cpp::nullopt;
- cp += result.parsed_len;
- if (*cp == '\0' || internal::isspace(*cp))
+ src.remove_prefix(result.parsed_len);
+ if (src.empty() || internal::isspace(src[0]))
break;
- if (*cp != '.')
+ if (src[0] != '.')
return cpp::nullopt;
- ++cp;
+ src.remove_prefix(1);
}
if (dot_num > IPV4_MAX_DOT_NUM)
return cpp::nullopt;
- // converts the Internet host address cp from the IPv4 numbers-and-dots
+ // converts the Internet host address src from the IPv4 numbers-and-dots
// notation (a[.b[.c[.d]]]) into binary form (in network byte order)
in_addr_t result = 0;
for (int i = 0; i <= dot_num; ++i) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/net/address.h b/deps/v8/third_party/llvm-libc/src/src/__support/net/address.h
index 082cf7a1878..7c799b122e4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/net/address.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/net/address.h
@@ -19,12 +19,13 @@
#include "hdr/types/struct_in_addr.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/span.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace net {
-cpp::optional<in_addr_t> inet_addr(const char *cp);
+cpp::optional<in_addr_t> inet_addr(cpp::string_view src);
/// Writes a string representation (including the terminating \0) of the
/// provided address into the destination buffer. In case of error, returns
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/CMakeLists.txt
index 3617bb7ac1e..2634dab56ee 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/CMakeLists.txt
@@ -85,6 +85,7 @@ add_header_library(
libc.include.inttypes
libc.src.__support.CPP.string_view
libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.properties.types
libc.hdr.errno_macros
)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/char_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/char_converter.h
index 59f3e22f7ce..7bad28d18d1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/char_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/char_converter.h
@@ -26,8 +26,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-LIBC_INLINE int convert_char(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_char(Writer<mode> *writer,
const FormatSection &to_conv) {
char buffer[MB_LEN_MAX];
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/converter.h
index 67d0ee3d42b..05ef6829b3a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/converter.h
@@ -29,8 +29,8 @@ namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
-LIBC_PRINTF_MODULE((template <WriteMode write_mode>
- int convert_float(Writer<write_mode> *writer,
+LIBC_PRINTF_MODULE((template <OverflowMode mode>
+ int convert_float(Writer<mode> *writer,
const FormatSection &to_conv)),
{
switch (to_conv.conv_name) {
@@ -52,18 +52,18 @@ LIBC_PRINTF_MODULE((template <WriteMode write_mode>
#endif // not LIBC_COPT_PRINTF_DISABLE_FLOAT
#ifdef LIBC_PRINTF_DEFINE_MODULES
-#define HANDLE_WRITE_MODE(MODE) \
- template int convert_float<WriteMode::MODE>( \
- Writer<WriteMode::MODE> * writer, const FormatSection &to_conv);
-#include "src/__support/printf_core/write_modes.def"
-#undef HANDLE_WRITE_MODE
+#define HANDLE_OVERFLOW_MODE(MODE) \
+ template int convert_float<OverflowMode::MODE>( \
+ Writer<OverflowMode::MODE> * writer, const FormatSection &to_conv);
+#include "src/__support/printf_core/overflow_modes.def"
+#undef HANDLE_OVERFLOW_MODE
#endif // LIBC_PRINTF_DEFINE_MODULES
// convert will call a conversion function to convert the FormatSection into
// its string representation, and then that will write the result to the
// writer.
-template <WriteMode write_mode>
-int convert(Writer<write_mode> *writer, const FormatSection &to_conv) {
+template <OverflowMode mode>
+int convert(Writer<mode> *writer, const FormatSection &to_conv) {
if (!to_conv.has_conv)
return writer->write(to_conv.raw_string);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/core_structs.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/core_structs.h
index 3107b9ce46f..13ba18b8ba1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/core_structs.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/core_structs.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/properties/types.h"
#include "src/__support/printf_core/printf_config.h"
#include <inttypes.h>
@@ -22,6 +23,22 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
+template <typename CharT, char ascii_value> struct CharConstant {};
+
+template <char ascii_value> struct CharConstant<char, ascii_value> {
+ LIBC_INLINE_VAR static constexpr char value = ascii_value;
+};
+
+#if defined(LIBC_TYPES_WCHAR_T_IS_UTF32)
+template <char ascii_value> struct CharConstant<wchar_t, ascii_value> {
+ LIBC_INLINE_VAR static constexpr wchar_t value = ascii_value;
+};
+#endif // LIBC_TYPES_WCHAR_T_IS_UTF32
+
+template <typename CharT, char ascii_value>
+LIBC_INLINE_VAR constexpr CharT char_constant_v =
+ CharConstant<CharT, ascii_value>::value;
+
// These length modifiers match the length modifiers in the format string, which
// is why they are formatted differently from the rest of the file.
enum class LengthModifier {
@@ -66,10 +83,10 @@ enum FormatFlags : uint8_t {
// locale_digits = 0x40, // I
};
-struct FormatSection {
+template <typename CharT> struct BasicFormatSection {
bool has_conv;
- cpp::string_view raw_string;
+ cpp::basic_string_view<CharT> raw_string;
// Format Specifier Values
FormatFlags flags = FormatFlags(0);
@@ -81,11 +98,11 @@ struct FormatSection {
AnyFloatStorageType conv_val_raw;
void *conv_val_ptr;
- char conv_name;
+ CharT conv_name;
// This operator is only used for testing and should be automatically
// optimized out for release builds.
- LIBC_INLINE bool operator==(const FormatSection &other) const {
+ LIBC_INLINE bool operator==(const BasicFormatSection &other) const {
if (has_conv != other.has_conv)
return false;
@@ -101,15 +118,19 @@ struct FormatSection {
(conv_name == other.conv_name)))
return false;
- if (conv_name == 'p' || conv_name == 'n' || conv_name == 's')
+ if (conv_name == char_constant_v<CharT, 'p'> ||
+ conv_name == char_constant_v<CharT, 'n'> ||
+ conv_name == char_constant_v<CharT, 's'>)
return (conv_val_ptr == other.conv_val_ptr);
- else if (conv_name != '%')
+ else if (conv_name != char_constant_v<CharT, '%'>)
return (conv_val_raw == other.conv_val_raw);
}
return true;
}
};
+using FormatSection = BasicFormatSection<char>;
+
enum PrimaryType : uint8_t {
Unknown = 0,
Float = 1,
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/fixed_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/fixed_converter.h
index 76b2d0d6364..04994a7729b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/fixed_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/fixed_converter.h
@@ -63,8 +63,8 @@ LIBC_INLINE constexpr uint32_t const_ten_exp(uint32_t exponent) {
} \
} while (false)
-template <WriteMode write_mode>
-LIBC_INLINE int convert_fixed(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_fixed(Writer<mode> *writer,
const FormatSection &to_conv) {
// Long accum should be the largest type, so we can store all the smaller
// numbers in things sized for it.
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter.h
index b678cd29cdb..89ea766e72f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter.h
@@ -99,7 +99,7 @@ zero_after_digits(int32_t base_2_exp, int32_t digits_after_point, T mantissa,
return has_trailing_zeros;
}
-template <WriteMode write_mode> class PaddingWriter {
+template <OverflowMode mode> class PaddingWriter {
bool left_justified = false;
bool leading_zeroes = false;
char sign_char = 0;
@@ -113,7 +113,7 @@ public:
sign_char(init_sign_char),
min_width(to_conv.min_width > 0 ? to_conv.min_width : 0) {}
- LIBC_INLINE int write_left_padding(Writer<write_mode> *writer,
+ LIBC_INLINE int write_left_padding(Writer<mode> *writer,
size_t total_digits) {
// The pattern is (spaces) (sign) (zeroes), but only one of spaces and
// zeroes can be written, and only if the padding amount is positive.
@@ -137,7 +137,7 @@ public:
return 0;
}
- LIBC_INLINE int write_right_padding(Writer<write_mode> *writer,
+ LIBC_INLINE int write_right_padding(Writer<mode> *writer,
size_t total_digits) {
// If and only if the conversion is left justified, there may be trailing
// spaces.
@@ -163,7 +163,7 @@ public:
This FloatWriter class does the buffering and counting, and writes to the
output when necessary.
*/
-template <WriteMode write_mode> class FloatWriter {
+template <OverflowMode mode> class FloatWriter {
char block_buffer[BLOCK_SIZE]; // The buffer that holds a block.
size_t buffered_digits = 0; // The number of digits held in the buffer.
bool has_written = false; // True once any digits have been output.
@@ -172,8 +172,8 @@ template <WriteMode write_mode> class FloatWriter {
size_t digits_before_decimal = 0; // The # of digits to write before the '.'
size_t total_digits_written = 0; // The # of digits that have been output.
bool has_decimal_point; // True if the number has a decimal point.
- Writer<write_mode> *writer; // Writes to the final output.
- PaddingWriter<write_mode>
+ Writer<mode> *writer; // Writes to the final output.
+ PaddingWriter<mode>
padding_writer; // Handles prefixes/padding, uses total_digits.
LIBC_INLINE int flush_buffer(bool round_up_max_blocks = false) {
@@ -255,9 +255,9 @@ template <WriteMode write_mode> class FloatWriter {
#endif // LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE
public:
- LIBC_INLINE FloatWriter(Writer<write_mode> *init_writer,
+ LIBC_INLINE FloatWriter(Writer<mode> *init_writer,
bool init_has_decimal_point,
- const PaddingWriter<write_mode> &init_padding_writer)
+ const PaddingWriter<mode> &init_padding_writer)
: has_decimal_point(init_has_decimal_point), writer(init_writer),
padding_writer(init_padding_writer) {}
@@ -480,23 +480,16 @@ public:
};
// Class-template auto deduction helpers, add more if needed.
-FloatWriter(Writer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>, bool,
- const PaddingWriter<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>)
- -> FloatWriter<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>;
-FloatWriter(Writer<WriteMode::RESIZE_AND_FILL_BUFF>, bool,
- const PaddingWriter<WriteMode::RESIZE_AND_FILL_BUFF>)
- -> FloatWriter<WriteMode::RESIZE_AND_FILL_BUFF>;
-FloatWriter(Writer<WriteMode::FLUSH_TO_STREAM>, bool,
- const PaddingWriter<WriteMode::FLUSH_TO_STREAM>)
- -> FloatWriter<WriteMode::FLUSH_TO_STREAM>;
+template <OverflowMode mode>
+FloatWriter(Writer<mode>, bool, const PaddingWriter<mode>) -> FloatWriter<mode>;
// This implementation is based on the Ryu Printf algorithm by Ulf Adams:
// Ulf Adams. 2019. Ryū revisited: printf floating point conversion.
// Proc. ACM Program. Lang. 3, OOPSLA, Article 169 (October 2019), 23 pages.
// https://doi.org/10.1145/3360595
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_decimal_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_decimal_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
// signed because later we use -FRACTION_LEN
@@ -523,7 +516,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer<write_mode> *writer,
// ignored.
bool nonzero = false;
- PaddingWriter<write_mode> padding_writer(to_conv, sign_char);
+ PaddingWriter<mode> padding_writer(to_conv, sign_char);
FloatWriter float_writer(writer, has_decimal_point, padding_writer);
FloatToString<T> float_converter(float_bits.get_val());
@@ -604,9 +597,9 @@ LIBC_INLINE int convert_float_decimal_typed(Writer<write_mode> *writer,
return WRITE_OK;
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_dec_exp_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_dec_exp_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
// signed because later we use -FRACTION_LEN
@@ -628,7 +621,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer<write_mode> *writer,
bool has_decimal_point =
(precision > 0) || ((to_conv.flags & FormatFlags::ALTERNATE_FORM) != 0);
- PaddingWriter<write_mode> padding_writer(to_conv, sign_char);
+ PaddingWriter<mode> padding_writer(to_conv, sign_char);
FloatWriter float_writer(writer, has_decimal_point, padding_writer);
FloatToString<T> float_converter(float_bits.get_val());
@@ -765,9 +758,9 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer<write_mode> *writer,
return WRITE_OK;
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_dec_auto_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
// signed because later we use -FRACTION_LEN
@@ -1133,8 +1126,8 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer,
// TODO: unify the float converters to remove the duplicated checks for inf/nan.
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_decimal(Writer<mode> *writer,
const FormatSection &to_conv) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
if (to_conv.length_modifier == LengthModifier::Q) {
@@ -1169,8 +1162,8 @@ LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
return convert_inf_nan(writer, to_conv);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_dec_exp(Writer<mode> *writer,
const FormatSection &to_conv) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
if (to_conv.length_modifier == LengthModifier::Q) {
@@ -1205,8 +1198,8 @@ LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
return convert_inf_nan(writer, to_conv);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_dec_auto(Writer<mode> *writer,
const FormatSection &to_conv) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
if (to_conv.length_modifier == LengthModifier::Q) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter_limited.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter_limited.h
index 2e34004ce92..7aa886db37a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter_limited.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_dec_converter_limited.h
@@ -374,8 +374,8 @@ DigitsOutput decimal_digits(DigitsInput input, int precision, bool e_mode) {
return output;
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_inner(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_inner(Writer<mode> *writer,
const FormatSection &to_conv,
int32_t fraction_len, int exponent,
AnyFloatStorageType mantissa, Sign sign,
@@ -618,10 +618,10 @@ LIBC_INLINE int convert_float_inner(Writer<write_mode> *writer,
return WRITE_OK;
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE int
-convert_float_typed(Writer<write_mode> *writer, const FormatSection &to_conv,
+convert_float_typed(Writer<mode> *writer, const FormatSection &to_conv,
fputil::FPBits<T> float_bits, ConversionType ctype) {
return convert_float_inner(writer, to_conv, float_bits.FRACTION_LEN,
float_bits.get_explicit_exponent(),
@@ -629,8 +629,8 @@ convert_float_typed(Writer<write_mode> *writer, const FormatSection &to_conv,
float_bits.sign(), ctype);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_outer(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_outer(Writer<mode> *writer,
const FormatSection &to_conv,
ConversionType ctype) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
@@ -666,44 +666,44 @@ LIBC_INLINE int convert_float_outer(Writer<write_mode> *writer,
return convert_inf_nan(writer, to_conv);
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_decimal_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_decimal_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::F);
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_dec_exp_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_dec_exp_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::E);
}
-template <typename T, WriteMode write_mode,
+template <typename T, OverflowMode mode,
cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int convert_float_dec_auto_typed(Writer<write_mode> *writer,
+LIBC_INLINE int convert_float_dec_auto_typed(Writer<mode> *writer,
const FormatSection &to_conv,
fputil::FPBits<T> float_bits) {
return convert_float_typed<T>(writer, to_conv, float_bits, ConversionType::G);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_decimal(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_decimal(Writer<mode> *writer,
const FormatSection &to_conv) {
return convert_float_outer(writer, to_conv, ConversionType::F);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_exp(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_dec_exp(Writer<mode> *writer,
const FormatSection &to_conv) {
return convert_float_outer(writer, to_conv, ConversionType::E);
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_dec_auto(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_dec_auto(Writer<mode> *writer,
const FormatSection &to_conv) {
return convert_float_outer(writer, to_conv, ConversionType::G);
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_hex_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_hex_converter.h
index 640db7be2c0..15f3d9f05a1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_hex_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_hex_converter.h
@@ -47,8 +47,8 @@ get_float_hex_exp_fp_bits_properties(AnyFloatStorageType float_raw) {
};
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_float_hex_exp(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_float_hex_exp(Writer<mode> *writer,
const FormatSection &to_conv) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
static constexpr uint32_t MAX_POSSIBLE_FRACTION_LEN =
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_inf_nan_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_inf_nan_converter.h
index 81769ae4b49..40740c701d9 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_inf_nan_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/float_inf_nan_converter.h
@@ -38,8 +38,8 @@ get_inf_nan_fp_bits_properties(AnyFloatStorageType float_raw) {
};
}
-template <WriteMode write_mode>
-LIBC_INLINE int convert_inf_nan(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_inf_nan(Writer<mode> *writer,
const FormatSection &to_conv) {
// All of the letters will be defined relative to variable a, which will be
// the appropriate case based on the case of the conversion.
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/int_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/int_converter.h
index c40c742e41c..786d9ff2268 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/int_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/int_converter.h
@@ -61,8 +61,8 @@ num_to_strview(uintmax_t num, cpp::span<char> bufref, char conv_name) {
} // namespace details
-template <WriteMode write_mode>
-LIBC_INLINE int convert_int(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_int(Writer<mode> *writer,
const FormatSection &to_conv) {
static constexpr size_t BITS_IN_BYTE = 8;
static constexpr size_t BITS_IN_NUM = sizeof(uintmax_t) * BITS_IN_BYTE;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_modes.def b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/overflow_modes.def
similarity index 70%
rename from deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_modes.def
rename to deps/v8/third_party/llvm-libc/src/src/__support/printf_core/overflow_modes.def
index fdce4d0241f..8fc1e620ed7 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_modes.def
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/overflow_modes.def
@@ -6,7 +6,5 @@
//
//===----------------------------------------------------------------------===//
-HANDLE_WRITE_MODE(FILL_BUFF_AND_DROP_OVERFLOW)
-HANDLE_WRITE_MODE(FLUSH_TO_STREAM)
-HANDLE_WRITE_MODE(RESIZE_AND_FILL_BUFF)
-HANDLE_WRITE_MODE(RUNTIME_DISPATCH)
+HANDLE_OVERFLOW_MODE(DROP_OVERFLOW)
+HANDLE_OVERFLOW_MODE(CALLBACK)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/parser.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/parser.h
index 72a521d15a6..efc3f38c108 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/parser.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/parser.h
@@ -76,8 +76,8 @@ template <typename T> using int_type_of_v = typename int_type_of<T>::type;
dst = cpp::bit_cast<int_type_of_v<arg_type>>(get_next_arg_value<arg_type>())
#endif // LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
-template <typename ArgProvider> class Parser {
- const char *__restrict str;
+template <typename ArgProvider, typename CharT> class Parser {
+ const CharT *__restrict str;
size_t cur_pos = 0;
ArgProvider args_cur;
@@ -105,10 +105,10 @@ template <typename ArgProvider> class Parser {
public:
#ifndef LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
- LIBC_INLINE Parser(const char *__restrict new_str, ArgProvider &args)
+ LIBC_INLINE Parser(const CharT *__restrict new_str, ArgProvider &args)
: str(new_str), args_cur(args), args_start(args) {}
#else
- LIBC_INLINE Parser(const char *__restrict new_str, ArgProvider &args)
+ LIBC_INLINE Parser(const CharT *__restrict new_str, ArgProvider &args)
: str(new_str), args_cur(args) {}
#endif // LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
@@ -116,10 +116,10 @@ public:
// specified format section. This can either be a raw format section with no
// conversion, or a format section with a conversion that has all of its
// variables stored in the format section.
- LIBC_INLINE FormatSection get_next_section() {
- FormatSection section;
+ LIBC_INLINE BasicFormatSection<CharT> get_next_section() {
+ BasicFormatSection<CharT> section;
size_t starting_pos = cur_pos;
- if (str[cur_pos] == '%') {
+ if (str[cur_pos] == char_constant_v<CharT, '%'>) {
// format section
section.has_conv = true;
@@ -134,7 +134,7 @@ public:
// handle width
section.min_width = 0;
- if (str[cur_pos] == '*') {
+ if (str[cur_pos] == char_constant_v<CharT, '*'>) {
++cur_pos;
WRITE_ARG_VAL_SIMPLEST(section.min_width, int, parse_index(&cur_pos));
@@ -152,11 +152,11 @@ public:
// handle precision
section.precision = -1; // negative precisions are ignored.
- if (str[cur_pos] == '.') {
+ if (str[cur_pos] == char_constant_v<CharT, '.'>) {
++cur_pos;
section.precision = 0; // if there's a . but no specified precision, the
// precision is implicitly 0.
- if (str[cur_pos] == '*') {
+ if (str[cur_pos] == char_constant_v<CharT, '*'>) {
++cur_pos;
WRITE_ARG_VAL_SIMPLEST(section.precision, int, parse_index(&cur_pos));
@@ -173,7 +173,7 @@ public:
section.conv_name = str[cur_pos];
section.bit_width = bw;
switch (str[cur_pos]) {
- case ('%'):
+ case (char_constant_v<CharT, '%'>):
// Regardless of options, a % conversion is always safe. The standard
// says that "The complete conversion specification shall be %%" but it
// also says that "If a conversion specification is invalid, the
@@ -182,7 +182,7 @@ public:
// valid or invalid options.
section.has_conv = true;
break;
- case ('c'):
+ case (char_constant_v<CharT, 'c'>):
if (section.length_modifier == LengthModifier::l) {
#ifdef LIBC_COPT_PRINTF_DISABLE_WIDE
using WideCharArgType = int;
@@ -195,14 +195,14 @@ public:
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, int, conv_index);
}
break;
- case ('d'):
- case ('i'):
- case ('o'):
- case ('x'):
- case ('X'):
- case ('u'):
- case ('b'):
- case ('B'):
+ case (char_constant_v<CharT, 'd'>):
+ case (char_constant_v<CharT, 'i'>):
+ case (char_constant_v<CharT, 'o'>):
+ case (char_constant_v<CharT, 'x'>):
+ case (char_constant_v<CharT, 'X'>):
+ case (char_constant_v<CharT, 'u'>):
+ case (char_constant_v<CharT, 'b'>):
+ case (char_constant_v<CharT, 'B'>):
switch (lm) {
case (LengthModifier::hh):
case (LengthModifier::h):
@@ -255,14 +255,14 @@ public:
}
break;
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
- case ('f'):
- case ('F'):
- case ('e'):
- case ('E'):
- case ('a'):
- case ('A'):
- case ('g'):
- case ('G'):
+ case (char_constant_v<CharT, 'f'>):
+ case (char_constant_v<CharT, 'F'>):
+ case (char_constant_v<CharT, 'e'>):
+ case (char_constant_v<CharT, 'E'>):
+ case (char_constant_v<CharT, 'a'>):
+ case (char_constant_v<CharT, 'A'>):
+ case (char_constant_v<CharT, 'g'>):
+ case (char_constant_v<CharT, 'G'>):
switch (lm) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
case (LengthModifier::Q):
@@ -283,15 +283,15 @@ public:
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
// Capitalization represents sign, but we only need to get the right
// bitwidth here so we ignore that.
- case ('r'):
- case ('R'):
+ case (char_constant_v<CharT, 'r'>):
+ case (char_constant_v<CharT, 'R'>):
// all fract sizes we support are less than 32 bits, and currently doing
// va_args with fixed point types just doesn't work.
// TODO: Move to fixed point types once va_args supports it.
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, uint32_t, conv_index);
break;
- case ('k'):
- case ('K'):
+ case (char_constant_v<CharT, 'k'>):
+ case (char_constant_v<CharT, 'K'>):
if (lm == LengthModifier::l) {
WRITE_ARG_VAL_SIMPLEST(section.conv_val_raw, uint64_t, conv_index);
} else {
@@ -300,7 +300,7 @@ public:
break;
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
- case ('m'):
+ case (char_constant_v<CharT, 'm'>):
// %m is an odd conversion in that it doesn't consume an argument, it
// just takes the current value of errno as its argument.
section.conv_val_raw =
@@ -308,12 +308,12 @@ public:
break;
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
- case ('n'): // Intentional fallthrough
+ case (char_constant_v<CharT, 'n'>): // Intentional fallthrough
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
- case ('p'):
+ case (char_constant_v<CharT, 'p'>):
WRITE_ARG_VAL_SIMPLEST(section.conv_val_ptr, void *, conv_index);
break;
- case ('s'):
+ case (char_constant_v<CharT, 's'>):
WRITE_ARG_VAL_SIMPLEST(section.conv_val_ptr, void *, conv_index);
break;
default:
@@ -323,13 +323,14 @@ public:
}
// If the end of the format section is on the '\0'. This means we need to
// not advance the cur_pos.
- if (str[cur_pos] != '\0')
+ if (str[cur_pos] != char_constant_v<CharT, '\0'>)
++cur_pos;
} else {
// raw section
section.has_conv = false;
- while (str[cur_pos] != '%' && str[cur_pos] != '\0')
+ while (str[cur_pos] != char_constant_v<CharT, '%'> &&
+ str[cur_pos] != char_constant_v<CharT, '\0'>)
++cur_pos;
}
section.raw_string = {str + starting_pos, cur_pos - starting_pos};
@@ -346,19 +347,19 @@ private:
FormatFlags flags = FormatFlags(0);
while (found_flag) {
switch (str[*local_pos]) {
- case '-':
+ case char_constant_v<CharT, '-'>:
flags = static_cast<FormatFlags>(flags | FormatFlags::LEFT_JUSTIFIED);
break;
- case '+':
+ case char_constant_v<CharT, '+'>:
flags = static_cast<FormatFlags>(flags | FormatFlags::FORCE_SIGN);
break;
- case ' ':
+ case char_constant_v<CharT, ' '>:
flags = static_cast<FormatFlags>(flags | FormatFlags::SPACE_PREFIX);
break;
- case '#':
+ case char_constant_v<CharT, '#'>:
flags = static_cast<FormatFlags>(flags | FormatFlags::ALTERNATE_FORM);
break;
- case '0':
+ case char_constant_v<CharT, '0'>:
flags = static_cast<FormatFlags>(flags | FormatFlags::LEADING_ZEROES);
break;
default:
@@ -376,8 +377,8 @@ private:
// after the format specifier if one is found.
LIBC_INLINE LengthSpec parse_length_modifier(size_t *local_pos) {
switch (str[*local_pos]) {
- case ('l'):
- if (str[*local_pos + 1] == 'l') {
+ case (char_constant_v<CharT, 'l'>):
+ if (str[*local_pos + 1] == char_constant_v<CharT, 'l'>) {
*local_pos += 2;
return {LengthModifier::ll, 0};
} else {
@@ -385,9 +386,9 @@ private:
return {LengthModifier::l, 0};
}
#ifndef LIBC_COPT_PRINTF_DISABLE_BITINT
- case ('w'): {
+ case (char_constant_v<CharT, 'w'>): {
LengthModifier lm;
- if (str[*local_pos + 1] == 'f') {
+ if (str[*local_pos + 1] == char_constant_v<CharT, 'f'>) {
*local_pos += 2;
lm = LengthModifier::wf;
} else {
@@ -402,29 +403,29 @@ private:
return {lm, 0};
}
#endif // LIBC_COPT_PRINTF_DISABLE_BITINT
- case ('h'):
- if (str[*local_pos + 1] == 'h') {
+ case (char_constant_v<CharT, 'h'>):
+ if (str[*local_pos + 1] == char_constant_v<CharT, 'h'>) {
*local_pos += 2;
return {LengthModifier::hh, 0};
} else {
++*local_pos;
return {LengthModifier::h, 0};
}
- case ('L'):
+ case (char_constant_v<CharT, 'L'>):
++*local_pos;
return {LengthModifier::L, 0};
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
- case ('Q'):
+ case (char_constant_v<CharT, 'Q'>):
++*local_pos;
return {LengthModifier::Q, 0};
#endif // LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128
- case ('j'):
+ case (char_constant_v<CharT, 'j'>):
++*local_pos;
return {LengthModifier::j, 0};
- case ('z'):
+ case (char_constant_v<CharT, 'z'>):
++*local_pos;
return {LengthModifier::z, 0};
- case ('t'):
+ case (char_constant_v<CharT, 't'>):
++*local_pos;
return {LengthModifier::t, 0};
default:
@@ -452,7 +453,8 @@ private:
if (internal::isdigit(str[*local_pos])) {
auto result = internal::strtointeger<int>(str + *local_pos, 10);
size_t index = static_cast<size_t>(result.value);
- if (str[*local_pos + static_cast<size_t>(result.parsed_len)] != '$')
+ if (str[*local_pos + static_cast<size_t>(result.parsed_len)] !=
+ char_constant_v<CharT, '$'>)
return 0;
*local_pos = static_cast<size_t>(1 + result.parsed_len) + *local_pos;
return index;
@@ -562,7 +564,7 @@ private:
size_t local_pos = 0;
while (str[local_pos]) {
- if (str[local_pos] == '%') {
+ if (str[local_pos] == char_constant_v<CharT, '%'>) {
++local_pos;
size_t conv_index = parse_index(&local_pos);
@@ -572,7 +574,7 @@ private:
parse_flags(&local_pos);
// handle width
- if (str[local_pos] == '*') {
+ if (str[local_pos] == char_constant_v<CharT, '*'>) {
++local_pos;
size_t width_index = parse_index(&local_pos);
@@ -586,9 +588,9 @@ private:
}
// handle precision
- if (str[local_pos] == '.') {
+ if (str[local_pos] == char_constant_v<CharT, '.'>) {
++local_pos;
- if (str[local_pos] == '*') {
+ if (str[local_pos] == char_constant_v<CharT, '*'>) {
++local_pos;
size_t precision_index = parse_index(&local_pos);
@@ -609,17 +611,17 @@ private:
// logic has been for skipping past this conversion properly to avoid
// weirdness with %%.
if (conv_index == 0) {
- if (str[local_pos] != '\0')
+ if (str[local_pos] != char_constant_v<CharT, '\0'>)
++local_pos;
continue;
}
TypeDesc conv_size = type_desc_from_type<void>();
switch (str[local_pos]) {
- case ('%'):
+ case (char_constant_v<CharT, '%'>):
conv_size = type_desc_from_type<void>();
break;
- case ('c'):
+ case (char_constant_v<CharT, 'c'>):
if (lm == LengthModifier::l) {
#ifdef LIBC_COPT_PRINTF_DISABLE_WIDE
using WideCharArgType = int;
@@ -631,14 +633,14 @@ private:
conv_size = type_desc_from_type<int>();
}
break;
- case ('d'):
- case ('i'):
- case ('o'):
- case ('x'):
- case ('X'):
- case ('u'):
- case ('b'):
- case ('B'):
+ case (char_constant_v<CharT, 'd'>):
+ case (char_constant_v<CharT, 'i'>):
+ case (char_constant_v<CharT, 'o'>):
+ case (char_constant_v<CharT, 'x'>):
+ case (char_constant_v<CharT, 'X'>):
+ case (char_constant_v<CharT, 'u'>):
+ case (char_constant_v<CharT, 'b'>):
+ case (char_constant_v<CharT, 'B'>):
switch (lm) {
case (LengthModifier::hh):
case (LengthModifier::h):
@@ -684,14 +686,14 @@ private:
}
break;
#ifndef LIBC_COPT_PRINTF_DISABLE_FLOAT
- case ('f'):
- case ('F'):
- case ('e'):
- case ('E'):
- case ('a'):
- case ('A'):
- case ('g'):
- case ('G'):
+ case (char_constant_v<CharT, 'f'>):
+ case (char_constant_v<CharT, 'F'>):
+ case (char_constant_v<CharT, 'e'>):
+ case (char_constant_v<CharT, 'E'>):
+ case (char_constant_v<CharT, 'a'>):
+ case (char_constant_v<CharT, 'A'>):
+ case (char_constant_v<CharT, 'g'>):
+ case (char_constant_v<CharT, 'G'>):
switch (lm) {
#if defined(LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128)
case LengthModifier::Q:
@@ -712,12 +714,12 @@ private:
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
// Capitalization represents sign, but we only need to get the right
// bitwidth here so we ignore that.
- case ('r'):
- case ('R'):
+ case (char_constant_v<CharT, 'r'>):
+ case (char_constant_v<CharT, 'R'>):
conv_size = type_desc_from_type<uint32_t>();
break;
- case ('k'):
- case ('K'):
+ case (char_constant_v<CharT, 'k'>):
+ case (char_constant_v<CharT, 'K'>):
if (lm == LengthModifier::l) {
conv_size = type_desc_from_type<uint64_t>();
} else {
@@ -726,10 +728,10 @@ private:
break;
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
- case ('n'):
+ case (char_constant_v<CharT, 'n'>):
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
- case ('p'):
- case ('s'):
+ case (char_constant_v<CharT, 'p'>):
+ case (char_constant_v<CharT, 's'>):
conv_size = type_desc_from_type<void *>();
break;
default:
@@ -743,7 +745,7 @@ private:
}
// If the end of the format section is on the '\0'. This means we need to
// not advance the local_pos.
- if (str[local_pos] != '\0')
+ if (str[local_pos] != char_constant_v<CharT, '\0'>)
++local_pos;
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_main.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_main.h
index b08e05be253..401adb0735d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_main.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_main.h
@@ -22,11 +22,11 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-ErrorOr<size_t> printf_main_modular(Writer<write_mode> *writer,
+template <OverflowMode mode>
+ErrorOr<size_t> printf_main_modular(Writer<mode> *writer,
const char *__restrict str,
internal::ArgList &args) {
- Parser<internal::ArgList> parser(str, args);
+ Parser<internal::ArgList, char> parser(str, args);
int result = 0;
for (FormatSection cur_section = parser.get_next_section();
!cur_section.raw_string.empty();
@@ -42,9 +42,8 @@ ErrorOr<size_t> printf_main_modular(Writer<write_mode> *writer,
return writer->get_chars_written();
}
-template <WriteMode write_mode>
-ErrorOr<size_t> printf_main(Writer<write_mode> *writer,
- const char *__restrict str,
+template <OverflowMode mode>
+ErrorOr<size_t> printf_main(Writer<mode> *writer, const char *__restrict str,
internal::ArgList &args) {
#ifdef LIBC_COPT_PRINTF_MODULAR
LIBC_INLINE_ASM(".reloc ., BFD_RELOC_NONE, __printf_float");
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/ptr_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/ptr_converter.h
index 692933a63f3..6415439bbb2 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/ptr_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/ptr_converter.h
@@ -18,8 +18,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-LIBC_INLINE int convert_pointer(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_pointer(Writer<mode> *writer,
const FormatSection &to_conv) {
FormatSection new_conv = to_conv;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/strerror_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/strerror_converter.h
index ec02a9a52f9..4e4e61295b5 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/strerror_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/strerror_converter.h
@@ -19,8 +19,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-LIBC_INLINE int convert_strerror(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_strerror(Writer<mode> *writer,
const FormatSection &to_conv) {
FormatSection new_conv = to_conv;
const int error_num = static_cast<int>(to_conv.conv_val_raw);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/string_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/string_converter.h
index 4cd1d52a2ba..5352bd8306b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/string_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/string_converter.h
@@ -27,8 +27,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-LIBC_INLINE int char_writer(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int char_writer(Writer<mode> *writer,
const FormatSection &to_conv) {
const char *str_ptr = reinterpret_cast<const char *>(to_conv.conv_val_ptr);
size_t string_len = 0;
@@ -66,8 +66,8 @@ LIBC_INLINE int char_writer(Writer<write_mode> *writer,
}
#ifndef LIBC_COPT_PRINTF_DISABLE_WIDE
-template <WriteMode write_mode>
-LIBC_INLINE int wchar_writer(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int wchar_writer(Writer<mode> *writer,
const FormatSection &to_conv) {
size_t string_len = 0;
const char32_t *wstr_ptr =
@@ -121,8 +121,8 @@ LIBC_INLINE int wchar_writer(Writer<write_mode> *writer,
}
#endif // LIBC_COPT_PRINTF_DISABLE_WIDE
-template <WriteMode write_mode>
-LIBC_INLINE int convert_string(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_string(Writer<mode> *writer,
const FormatSection &to_conv) {
int ret = 0;
if (to_conv.length_modifier == LengthModifier::l) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vasprintf_internal.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vasprintf_internal.h
index 969da6ebc46..5421336bc33 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vasprintf_internal.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vasprintf_internal.h
@@ -21,24 +21,25 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-LIBC_INLINE int resize_overflow_hook(cpp::string_view new_str,
- ResizingBuffer *wb) {
- size_t new_size = new_str.size() + wb->buff_cur;
- const bool isBuffOnStack = (wb->buff == wb->init_buff);
+LIBC_INLINE int overflow_write_resize_buffer(WriteBuffer<char> &wb,
+ cpp::string_view new_str,
+ void *initial_stack_buffer) {
+ size_t new_size = new_str.size() + wb.buff_cur;
+ const bool is_buff_on_stack = (wb.buff == initial_stack_buffer);
char *new_buff = static_cast<char *>(
- isBuffOnStack ? malloc(new_size + 1)
- : realloc(wb->buff, new_size + 1)); // +1 for null
+ is_buff_on_stack ? malloc(new_size + 1)
+ : realloc(wb.buff, new_size + 1)); // +1 for null
if (new_buff == nullptr) {
- if (wb->buff != wb->init_buff)
- free(wb->buff);
+ if (!is_buff_on_stack)
+ free(wb.buff);
return ALLOCATION_ERROR;
}
- if (isBuffOnStack)
- inline_memcpy(new_buff, wb->buff, wb->buff_cur);
- wb->buff = new_buff;
- inline_memcpy(wb->buff + wb->buff_cur, new_str.data(), new_str.size());
- wb->buff_cur = new_size;
- wb->buff_len = new_size;
+ if (is_buff_on_stack)
+ inline_memcpy(new_buff, wb.buff, wb.buff_cur);
+ wb.buff = new_buff;
+ inline_memcpy(wb.buff + wb.buff_cur, new_str.data(), new_str.size());
+ wb.buff_cur = new_size;
+ wb.buff_len = new_size;
return printf_core::WRITE_OK;
}
@@ -49,9 +50,9 @@ LIBC_INLINE ErrorOr<size_t> vasprintf_internal(char **ret,
const char *__restrict format,
internal::ArgList args) {
char init_buff_on_stack[DEFAULT_BUFFER_SIZE];
- printf_core::ResizingBuffer wb(init_buff_on_stack, DEFAULT_BUFFER_SIZE,
- resize_overflow_hook);
- printf_core::Writer writer(wb);
+ printf_core::Writer writer = printf_core::make_writer(
+ init_buff_on_stack, DEFAULT_BUFFER_SIZE, &overflow_write_resize_buffer,
+ init_buff_on_stack);
auto ret_val = [&] {
if constexpr (use_modular)
@@ -63,13 +64,14 @@ LIBC_INLINE ErrorOr<size_t> vasprintf_internal(char **ret,
*ret = nullptr;
return ret_val;
}
- if (wb.buff == init_buff_on_stack) {
+ char *final_buff = writer.get_write_buffer().buff;
+ if (final_buff == init_buff_on_stack) {
*ret = static_cast<char *>(malloc(ret_val.value() + 1));
if (ret == nullptr)
return Error(ALLOCATION_ERROR);
- inline_memcpy(*ret, wb.buff, ret_val.value());
+ inline_memcpy(*ret, final_buff, ret_val.value());
} else {
- *ret = wb.buff;
+ *ret = final_buff;
}
(*ret)[ret_val.value()] = '\0';
return ret_val;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vfprintf_internal.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vfprintf_internal.h
index 6a62e966f7f..523eea30787 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vfprintf_internal.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/vfprintf_internal.h
@@ -86,16 +86,17 @@ LIBC_INLINE ErrorOr<size_t> vfprintf_internal(::FILE *__restrict stream,
internal::ArgList &args) {
constexpr size_t BUFF_SIZE = 1024;
char buffer[BUFF_SIZE];
- printf_core::FlushingBuffer wb(buffer, BUFF_SIZE, &file_write_hook,
- reinterpret_cast<void *>(stream));
- Writer writer(wb);
+ Writer writer =
+ make_writer(buffer, BUFF_SIZE,
+ &overflow_write_flush_to_sink<char, file_write_hook>, stream);
internal::flockfile(stream);
auto retval = printf_main(&writer, format, args);
if (!retval.has_value()) {
internal::funlockfile(stream);
return retval;
}
- int flushval = wb.flush_to_stream();
+ int flushval =
+ writer.get_write_buffer().flush_to_sink<file_write_hook>(stream);
if (flushval != WRITE_OK)
retval = Error(-flushval);
internal::funlockfile(stream);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_int_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_int_converter.h
index 906af324d10..882963c1c44 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_int_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/write_int_converter.h
@@ -19,8 +19,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-template <WriteMode write_mode>
-LIBC_INLINE int convert_write_int(Writer<write_mode> *writer,
+template <OverflowMode mode>
+LIBC_INLINE int convert_write_int(Writer<mode> *writer,
const FormatSection &to_conv) {
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/writer.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/writer.h
index e7d3fe530d7..031c48b3a35 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/writer.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/writer.h
@@ -21,206 +21,195 @@
namespace LIBC_NAMESPACE_DECL {
namespace printf_core {
-#define HANDLE_WRITE_MODE(MODE) MODE,
-enum class WriteMode {
-#include "src/__support/printf_core/write_modes.def"
+#define HANDLE_OVERFLOW_MODE(MODE) MODE,
+enum class OverflowMode {
+#include "src/__support/printf_core/overflow_modes.def"
};
-#undef HANDLE_WRITE_MODE
+#undef HANDLE_OVERFLOW_MODE
// Helper to omit the template argument if we are using runtime dispatch and
// avoid multiple copies of the converter functions.
-template <WriteMode write_mode> struct Mode {
+template <OverflowMode mode> struct Mode {
#ifdef LIBC_COPT_PRINTF_RUNTIME_DISPATCH
- static constexpr WriteMode value = WriteMode::RUNTIME_DISPATCH;
+ static constexpr OverflowMode value = OverflowMode::CALLBACK;
#else
- static constexpr WriteMode value = write_mode;
+ static constexpr OverflowMode value = mode;
#endif
};
-template <WriteMode write_mode> class Writer;
+// Function type for an optionally stateful write sink to be used in a
+// `Writer` "overflow write" callback.
+//
+// Should not be expected to handle an empty string input.
+template <typename CharT>
+using WriteSink = int (*)(cpp::basic_string_view<CharT> /* str */,
+ void * /* state */);
-template <WriteMode write_mode> struct WriteBuffer {
- char *buff;
+template <typename CharT> struct WriteBuffer {
+ CharT *buff;
size_t buff_len;
size_t buff_cur = 0;
- // The current writing mode in case the user wants runtime dispatch of the
- // stream writer with function pointers.
- [[maybe_unused]] WriteMode write_mode_;
-
-protected:
- LIBC_INLINE WriteBuffer(char *buff, size_t buff_len, WriteMode mode)
- : buff(buff), buff_len(buff_len), write_mode_(mode) {}
-
-private:
- friend class Writer<write_mode>;
- // The overflow_write method will handle the case when adding new_str to
- // the buffer would overflow it. Specific actions will depend on the buffer
- // type / write_mode.
- LIBC_INLINE int overflow_write(cpp::string_view new_str);
-};
-// Buffer variant that discards characters that don't fit into the buffer.
-struct DropOverflowBuffer
- : public WriteBuffer<Mode<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>::value> {
- LIBC_INLINE DropOverflowBuffer(char *buff, size_t buff_len)
- : WriteBuffer<Mode<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>::value>(
- buff, buff_len, WriteMode::FILL_BUFF_AND_DROP_OVERFLOW) {}
-
- LIBC_INLINE int fill_remaining_to_buff(cpp::string_view new_str) {
- if (buff_cur < buff_len) {
- size_t bytes_to_write = buff_len - buff_cur;
- if (bytes_to_write > new_str.size()) {
- bytes_to_write = new_str.size();
- }
- inline_memcpy(buff + buff_cur, new_str.data(), bytes_to_write);
- buff_cur += bytes_to_write;
- }
- return WRITE_OK;
+ // Flushes the current contents of the buffer to `write_sink`, if non-empty.
+ template <WriteSink<CharT> write_sink>
+ LIBC_INLINE int flush_to_sink(void *sink_state = nullptr) {
+ if (buff_cur == 0)
+ return WRITE_OK;
+
+ int retval = write_sink({buff, buff_cur}, sink_state);
+ if (retval >= 0)
+ buff_cur = 0;
+ return retval;
}
};
-// Buffer variant that flushes to stream when it gets full.
-struct FlushingBuffer
- : public WriteBuffer<Mode<WriteMode::FLUSH_TO_STREAM>::value> {
- // The stream writer will be called when the buffer is full. It will be passed
- // string_views to write to the stream.
- using StreamWriter = int (*)(cpp::string_view, void *);
- const StreamWriter stream_writer;
- void *output_target;
-
- LIBC_INLINE FlushingBuffer(char *buff, size_t buff_len, StreamWriter hook,
- void *target)
- : WriteBuffer<Mode<WriteMode::FLUSH_TO_STREAM>::value>(
- buff, buff_len, WriteMode::FLUSH_TO_STREAM),
- stream_writer(hook), output_target(target) {}
-
- // Flushes the entire current buffer to stream, followed by the new_str (if
- // non-empty).
- LIBC_INLINE int flush_to_stream(cpp::string_view new_str) {
- if (buff_cur > 0) {
- int retval = stream_writer({buff, buff_cur}, output_target);
- if (retval < 0)
- return retval;
- }
- if (new_str.size() > 0) {
- int retval = stream_writer(new_str, output_target);
- if (retval < 0)
- return retval;
- }
- buff_cur = 0;
- return WRITE_OK;
+// Function type for handling the "overflow write" slow path in `Writer` when
+// the `WriteBuffer` may not have enough remaining capacity for the new content.
+template <typename CharT>
+using OverflowWriteFn = int (*)(WriteBuffer<CharT> & /* wb */,
+ cpp::basic_string_view<CharT> /* new_str */,
+ void * /* state */);
+
+// Handles overflow by filling any remaining space in `wb` with the start of
+// `new_str`, and dropping any excess characters.
+template <typename CharT>
+LIBC_INLINE int
+overflow_write_drop_overflow(WriteBuffer<CharT> &wb,
+ cpp::basic_string_view<CharT> new_str, void *) {
+ if (wb.buff_cur < wb.buff_len) {
+ size_t chars_to_write = wb.buff_len - wb.buff_cur;
+ if (chars_to_write > new_str.size())
+ chars_to_write = new_str.size();
+ inline_memcpy(wb.buff + wb.buff_cur, new_str.data(),
+ chars_to_write * sizeof(CharT));
+ wb.buff_cur += chars_to_write;
}
+ return WRITE_OK;
+}
- LIBC_INLINE int flush_to_stream() { return flush_to_stream({}); }
-};
+// Flushes the current contents of `wb` to `write_sink`, followed by `new_str`.
+template <typename CharT, WriteSink<CharT> write_sink>
+LIBC_INLINE int
+overflow_write_flush_to_sink(WriteBuffer<CharT> &wb,
+ cpp::basic_string_view<CharT> new_str,
+ void *sink_state) {
+ int retval = wb.template flush_to_sink<write_sink>(sink_state);
+ if (retval < 0)
+ return retval;
+ if (new_str.size() > 0) {
+ retval = write_sink(new_str, sink_state);
+ if (retval < 0)
+ return retval;
+ }
+ return WRITE_OK;
+}
+
+// Helper template used by `Writer` to dispatch to the appropriate
+// `OverflowWriteFn`.
+template <OverflowMode mode, typename CharT> struct OverflowWriter;
-// Buffer variant that calls a resizing callback when it gets full.
-struct ResizingBuffer
- : public WriteBuffer<Mode<WriteMode::RESIZE_AND_FILL_BUFF>::value> {
- using ResizeWriter = int (*)(cpp::string_view, ResizingBuffer *);
- const ResizeWriter resize_writer;
- const char *init_buff; // for checking when resize.
-
- LIBC_INLINE ResizingBuffer(char *buff, size_t buff_len, ResizeWriter hook)
- : WriteBuffer<Mode<WriteMode::RESIZE_AND_FILL_BUFF>::value>(
- buff, buff_len, WriteMode::RESIZE_AND_FILL_BUFF),
- resize_writer(hook), init_buff(buff) {}
-
- // Invokes the callback that is supposed to resize the buffer and make
- // it large enough to fit the new_str addition.
- LIBC_INLINE int resize_and_write(cpp::string_view new_str) {
- return resize_writer(new_str, this);
+template <typename CharT>
+struct OverflowWriter<OverflowMode::DROP_OVERFLOW, CharT> {
+ LIBC_INLINE OverflowWriter(OverflowWriteFn<CharT>, void *) {}
+
+ LIBC_INLINE int write(WriteBuffer<CharT> &wb,
+ cpp::basic_string_view<CharT> new_str) {
+ return overflow_write_drop_overflow<CharT>(wb, new_str, nullptr);
}
};
-template <>
-LIBC_INLINE int WriteBuffer<WriteMode::RUNTIME_DISPATCH>::overflow_write(
- cpp::string_view new_str) {
- if (write_mode_ == WriteMode::FILL_BUFF_AND_DROP_OVERFLOW)
- return reinterpret_cast<DropOverflowBuffer *>(this)->fill_remaining_to_buff(
- new_str);
- else if (write_mode_ == WriteMode::FLUSH_TO_STREAM)
- return reinterpret_cast<FlushingBuffer *>(this)->flush_to_stream(new_str);
- else if (write_mode_ == WriteMode::RESIZE_AND_FILL_BUFF)
- return reinterpret_cast<ResizingBuffer *>(this)->resize_and_write(new_str);
- __builtin_unreachable();
-}
+template <typename CharT> struct OverflowWriter<OverflowMode::CALLBACK, CharT> {
+ OverflowWriteFn<CharT> runtime_fn;
+ void *state;
-template <>
-LIBC_INLINE int
-WriteBuffer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>::overflow_write(
- cpp::string_view new_str) {
- return reinterpret_cast<DropOverflowBuffer *>(this)->fill_remaining_to_buff(
- new_str);
-}
+ LIBC_INLINE OverflowWriter(OverflowWriteFn<CharT> runtime_fn, void *state)
+ : runtime_fn(runtime_fn), state(state) {}
-template <>
-LIBC_INLINE int WriteBuffer<WriteMode::FLUSH_TO_STREAM>::overflow_write(
- cpp::string_view new_str) {
- return reinterpret_cast<FlushingBuffer *>(this)->flush_to_stream(new_str);
-}
+ LIBC_INLINE int write(WriteBuffer<CharT> &wb,
+ cpp::basic_string_view<CharT> new_str) {
+ return runtime_fn(wb, new_str, state);
+ }
+};
-template <>
-LIBC_INLINE int WriteBuffer<WriteMode::RESIZE_AND_FILL_BUFF>::overflow_write(
- cpp::string_view new_str) {
- return reinterpret_cast<ResizingBuffer *>(this)->resize_and_write(new_str);
+// Fills the `dest` buffer with `count` copies of `value`.
+template <typename CharT>
+LIBC_INLINE void fill_buffer(CharT *dest, CharT value, size_t count) {
+ if constexpr (sizeof(CharT) == sizeof(unsigned char)) {
+ inline_memset(dest, static_cast<unsigned char>(value), count);
+ } else {
+ for (size_t i = 0; i < count; ++i)
+ dest[i] = value;
+ }
}
-template <WriteMode write_mode> class Writer final {
- WriteBuffer<write_mode> &wb;
+template <OverflowMode mode, typename CharT = char> class Writer final {
+ WriteBuffer<CharT> wb;
size_t chars_written = 0;
+ OverflowWriter<mode, CharT> overflow_writer;
- LIBC_INLINE int pad(char new_char, size_t length) {
+ LIBC_INLINE int pad(CharT new_char, size_t length) {
// First, fill as much of the buffer as possible with the padding char.
size_t written = 0;
const size_t buff_space = wb.buff_len - wb.buff_cur;
// ASSERT: length > buff_space
if (buff_space > 0) {
- inline_memset(wb.buff + wb.buff_cur, new_char, buff_space);
+ fill_buffer(wb.buff + wb.buff_cur, new_char, buff_space);
wb.buff_cur += buff_space;
written = buff_space;
}
// Next, overflow write the rest of length using the mini_buff.
constexpr size_t MINI_BUFF_SIZE = 64;
- char mini_buff[MINI_BUFF_SIZE];
- inline_memset(mini_buff, new_char, MINI_BUFF_SIZE);
- cpp::string_view mb_string_view(mini_buff, MINI_BUFF_SIZE);
+ CharT mini_buff[MINI_BUFF_SIZE];
+ fill_buffer(mini_buff, new_char, MINI_BUFF_SIZE);
+ cpp::basic_string_view<CharT> mb_string_view(mini_buff, MINI_BUFF_SIZE);
while (written + MINI_BUFF_SIZE < length) {
- int result = wb.overflow_write(mb_string_view);
+ int result = overflow_writer.write(wb, mb_string_view);
if (result != WRITE_OK)
return result;
written += MINI_BUFF_SIZE;
}
- cpp::string_view mb_substr = mb_string_view.substr(0, length - written);
- return wb.overflow_write(mb_substr);
+ cpp::basic_string_view<CharT> mb_substr =
+ mb_string_view.substr(0, length - written);
+ return overflow_writer.write(wb, mb_substr);
}
+ LIBC_INLINE Writer(CharT *buffer, size_t buffer_len,
+ OverflowWriter<mode, CharT> overflow_writer)
+ : wb{.buff = buffer, .buff_len = buffer_len},
+ overflow_writer(overflow_writer) {}
+
public:
- LIBC_INLINE Writer(WriteBuffer<write_mode> &wb) : wb(wb) {}
+ template <typename CharType>
+ friend Writer<Mode<OverflowMode::DROP_OVERFLOW>::value, CharType>
+ make_drop_overflow_writer(CharType *buffer, size_t buffer_len);
+
+ template <typename CharType>
+ friend Writer<Mode<OverflowMode::CALLBACK>::value, CharType>
+ make_writer(CharType *buffer, size_t buffer_len,
+ OverflowWriteFn<CharType> callback, void *callback_state);
// Takes a string, copies it into the buffer if there is space, else passes it
// to the overflow mechanism to be handled separately.
- LIBC_INLINE int write(cpp::string_view new_string) {
+ LIBC_INLINE int write(cpp::basic_string_view<CharT> new_string) {
chars_written += new_string.size();
if (LIBC_LIKELY(wb.buff_cur + new_string.size() <= wb.buff_len)) {
inline_memcpy(wb.buff + wb.buff_cur, new_string.data(),
- new_string.size());
+ new_string.size() * sizeof(CharT));
wb.buff_cur += new_string.size();
return WRITE_OK;
}
- return wb.overflow_write(new_string);
+ return overflow_writer.write(wb, new_string);
}
// Takes a char and a length, memsets the next length characters of the buffer
// if there is space, else calls pad which will loop and call the overflow
// mechanism on a secondary buffer.
- LIBC_INLINE int write(char new_char, size_t length) {
+ LIBC_INLINE int write(CharT new_char, size_t length) {
chars_written += length;
if (LIBC_LIKELY(wb.buff_cur + length <= wb.buff_len)) {
- inline_memset(wb.buff + wb.buff_cur, static_cast<unsigned char>(new_char),
- length);
+ fill_buffer(wb.buff + wb.buff_cur, new_char, length);
wb.buff_cur += length;
return WRITE_OK;
}
@@ -229,27 +218,41 @@ public:
// Takes a char, copies it into the buffer if there is space, else passes it
// to the overflow mechanism to be handled separately.
- LIBC_INLINE int write(char new_char) {
+ LIBC_INLINE int write(CharT new_char) {
chars_written += 1;
if (LIBC_LIKELY(wb.buff_cur + 1 <= wb.buff_len)) {
wb.buff[wb.buff_cur] = new_char;
wb.buff_cur += 1;
return WRITE_OK;
}
- cpp::string_view char_string_view(&new_char, 1);
- return wb.overflow_write(char_string_view);
+ return overflow_writer.write(wb, {&new_char, 1});
}
LIBC_INLINE size_t get_chars_written() { return chars_written; }
+
+ LIBC_INLINE WriteBuffer<CharT> &get_write_buffer() { return wb; }
};
-// Class-template auto deduction helpers.
-Writer(WriteBuffer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>)
- -> Writer<WriteMode::FILL_BUFF_AND_DROP_OVERFLOW>;
-Writer(WriteBuffer<WriteMode::RESIZE_AND_FILL_BUFF>)
- -> Writer<WriteMode::RESIZE_AND_FILL_BUFF>;
-Writer(WriteBuffer<WriteMode::FLUSH_TO_STREAM>)
- -> Writer<WriteMode::FLUSH_TO_STREAM>;
+// Class-template auto deduction helper.
+template <OverflowMode mode, typename CharT>
+Writer(CharT *, size_t, OverflowWriter<mode, CharT>) -> Writer<mode, CharT>;
+
+template <typename CharT>
+LIBC_INLINE Writer<Mode<OverflowMode::DROP_OVERFLOW>::value, CharT>
+make_drop_overflow_writer(CharT *buffer, size_t buffer_len) {
+ return Writer(buffer, buffer_len,
+ OverflowWriter<Mode<OverflowMode::DROP_OVERFLOW>::value, CharT>(
+ overflow_write_drop_overflow<CharT>, nullptr));
+}
+
+template <typename CharT>
+LIBC_INLINE Writer<OverflowMode::CALLBACK, CharT>
+make_writer(CharT *buffer, size_t buffer_len, OverflowWriteFn<CharT> callback,
+ void *callback_state = nullptr) {
+ return Writer(
+ buffer, buffer_len,
+ OverflowWriter<OverflowMode::CALLBACK, CharT>(callback, callback_state));
+}
} // namespace printf_core
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/pwd/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/CMakeLists.txt
new file mode 100644
index 00000000000..ccf32531ab6
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/CMakeLists.txt
@@ -0,0 +1,44 @@
+add_header_library(
+ field_tokenizer
+ HDRS
+ field_tokenizer.h
+ DEPENDS
+ libc.src.__support.CPP.optional
+ libc.src.__support.CPP.span
+ libc.src.__support.CPP.string_view
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ dynamic_buffer
+ HDRS
+ dynamic_buffer.h
+ DEPENDS
+ libc.hdr.func.free
+ libc.hdr.func.realloc
+ libc.hdr.types.size_t
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.span
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ flat_file_db
+ HDRS
+ flat_file_db.h
+ DEPENDS
+ .dynamic_buffer
+ libc.hdr.errno_macros
+ libc.hdr.stdio_macros
+ libc.hdr.types.size_t
+ libc.src.__support.CPP.functional
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.span
+ libc.src.__support.File.file
+ libc.src.__support.error_or
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/pwd/dynamic_buffer.h b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/dynamic_buffer.h
new file mode 100644
index 00000000000..44d269071c1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/dynamic_buffer.h
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Growable byte buffer with explicit lifetime management.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_PWD_DYNAMIC_BUFFER_H
+#define LLVM_LIBC_SRC___SUPPORT_PWD_DYNAMIC_BUFFER_H
+
+#include "hdr/func/free.h"
+#include "hdr/func/realloc.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/CPP/type_traits/is_trivially_destructible.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace pwd {
+
+// A heap-backed, growable byte buffer for the flat-file database engine.
+//
+// This type is trivially destructible by design, so an instance can be a
+// constant-initialised process global. The owner releases the storage
+// explicitly when done.
+class DynamicBuffer {
+ static constexpr size_t INITIAL_CAPACITY = 1024;
+
+ char *ptr = nullptr;
+ size_t cap = 0;
+
+public:
+ LIBC_INLINE constexpr DynamicBuffer() = default;
+
+ DynamicBuffer(const DynamicBuffer &) = delete;
+ DynamicBuffer &operator=(const DynamicBuffer &) = delete;
+
+ // Grows the buffer to hold at least new_capacity bytes, preserving the
+ // existing contents. Capacity doubles so that repeated growth stays linear
+ // in the number of bytes read. Returns false if allocation failed, in which
+ // case the buffer is left untouched.
+ [[nodiscard]] LIBC_INLINE bool reserve(size_t new_capacity) {
+ if (new_capacity <= cap)
+ return true;
+
+ size_t next = cap == 0 ? INITIAL_CAPACITY : cap;
+ while (next < new_capacity) {
+ if (next > cpp::numeric_limits<size_t>::max() / 2)
+ return false;
+ next *= 2;
+ }
+
+ void *new_ptr = ::realloc(ptr, next);
+ if (new_ptr == nullptr)
+ return false;
+
+ ptr = static_cast<char *>(new_ptr);
+ cap = next;
+ return true;
+ }
+
+ // Doubles the current capacity, or allocates the initial capacity when the
+ // buffer is empty. Returns false if allocation failed.
+ [[nodiscard]] LIBC_INLINE bool grow() {
+ if (cap == cpp::numeric_limits<size_t>::max())
+ return false;
+ return reserve(cap == 0 ? INITIAL_CAPACITY : cap + 1);
+ }
+
+ // Frees the storage and returns the buffer to its empty state. Safe to call
+ // more than once.
+ LIBC_INLINE void release() {
+ ::free(ptr);
+ ptr = nullptr;
+ cap = 0;
+ }
+
+ [[nodiscard]] LIBC_INLINE cpp::span<char> span() const { return {ptr, cap}; }
+ [[nodiscard]] LIBC_INLINE size_t capacity() const { return cap; }
+};
+
+static_assert(cpp::is_trivially_destructible<DynamicBuffer>::value,
+ "DynamicBuffer must be trivially destructible");
+
+// RAII wrapper around DynamicBuffer for stack-local buffers.
+class ScopedDynamicBuffer : public DynamicBuffer {
+public:
+ using DynamicBuffer::DynamicBuffer;
+
+ LIBC_INLINE ~ScopedDynamicBuffer() { this->release(); }
+};
+
+} // namespace pwd
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_PWD_DYNAMIC_BUFFER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/pwd/field_tokenizer.h b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/field_tokenizer.h
new file mode 100644
index 00000000000..fb827413953
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/field_tokenizer.h
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// In-place field tokenizer for colon-separated flat database files.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_PWD_FIELD_TOKENIZER_H
+#define LLVM_LIBC_SRC___SUPPORT_PWD_FIELD_TOKENIZER_H
+
+#include "src/__support/CPP/optional.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace pwd {
+
+// In-place field tokenizer for delimited database records.
+class FieldTokenizer {
+ cpp::span<char> data;
+ char separator;
+
+public:
+ LIBC_INLINE constexpr explicit FieldTokenizer(cpp::span<char> buf,
+ char sep = ':')
+ : data(buf), separator(sep) {}
+
+ // Extracts the next null-terminated field.
+ LIBC_INLINE cpp::optional<cpp::span<char>> next_field() {
+ if (data.empty())
+ return cpp::nullopt;
+
+ cpp::string_view sv(data.data(), data.size());
+ size_t pos = sv.find_first_of(separator);
+
+ // If a delimiter was found, replace it with a null terminator and return
+ // the field.
+ if (pos != cpp::string_view::npos) {
+ data[pos] = '\0';
+ auto field = data.first(pos + 1);
+ data = data.subspan(pos + 1);
+ return field;
+ }
+
+ // If null-terminated without delimiters, return the remaining span as the
+ // final field.
+ if (data.back() == '\0') {
+ auto field = data;
+ data = cpp::span<char>();
+ return field;
+ }
+
+ // Otherwise, no more fields remain.
+ return cpp::nullopt;
+ }
+};
+
+} // namespace pwd
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_PWD_FIELD_TOKENIZER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/pwd/flat_file_db.h b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/flat_file_db.h
new file mode 100644
index 00000000000..319197872cd
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/pwd/flat_file_db.h
@@ -0,0 +1,341 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Generic flat-file database template engine.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_PWD_FLAT_FILE_DB_H
+#define LLVM_LIBC_SRC___SUPPORT_PWD_FLAT_FILE_DB_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/stdio_macros.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/functional.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/File/file.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/pwd/dynamic_buffer.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace pwd {
+
+// Struct to hold the result of a line read operation.
+struct ReadLineResult {
+ size_t bytes_read;
+ bool truncated;
+ // True only when zero raw bytes were read because the stream was already at
+ // EOF. A blank line ("\n") or a final line without a trailing newline
+ // consumes at least one raw byte and returns eof == false (with
+ // bytes_read == 0 for "\n"); the following call returns eof == true.
+ bool eof;
+};
+
+// Parses a record in place and fills entry.
+// line is the record bytes including the terminating NUL (line.back() == '\0').
+// scratch is spare writable storage for auxiliary structures (such as pointer
+// arrays) and may be empty. Specialisations that require scratch storage must
+// return Error(ERANGE) prior to modifying the buffer if scratch is
+// insufficient.
+template <typename EntryType>
+ErrorOr<void> parse_line(cpp::span<char> line, cpp::span<char> scratch,
+ EntryType *entry);
+
+// Generic flat colon-delimited database engine.
+template <typename EntryType> class FlatFileDatabase {
+public:
+ using Matcher = cpp::function<bool(const EntryType &)>;
+
+private:
+ const char *file_path;
+ File *file = nullptr;
+
+ // Closes the file stream if open.
+ LIBC_INLINE ErrorOr<void> clear_file_stream() {
+ if (file) {
+ int result = file->close();
+ file = nullptr;
+ if (result != 0)
+ return Error(result);
+ }
+ return {};
+ }
+
+ // Reads a single line from the given file into the provided buffer, stripping
+ // any trailing '\n' and ensuring the result is null-terminated. A line too
+ // long for the buffer is reported as truncated.
+ //
+ // Note: POSIX getline/getdelim cannot be used here because user database
+ // iteration and lookups must operate in-place within a fixed, bounded buffer
+ // without dynamic heap allocations during getnext. See read_line_growing for
+ // the variant used by the non-reentrant interfaces, which own their buffer
+ // and may grow it.
+ LIBC_INLINE static ErrorOr<ReadLineResult> read_line(File *f,
+ cpp::span<char> buf) {
+ if (!f)
+ return Error(EINVAL);
+ if (buf.size() < 2)
+ return Error(ERANGE);
+
+ File::FileLock lock(f);
+ size_t bytes_read = 0;
+ FileIOResult result(0);
+ bool truncated = false;
+
+ for (char &ch : buf.first(buf.size() - 1)) {
+ result = f->read_unlocked(&ch, 1);
+ if (result.has_error())
+ return Error(result.error);
+ if (result.value != 1)
+ break;
+ ++bytes_read;
+ if (ch == '\n')
+ break;
+ }
+
+ bool eof = (bytes_read == 0);
+
+ auto read_span = buf.first(bytes_read);
+ if (result.value == 1 && !read_span.empty() && read_span.back() != '\n') {
+ char c = '\0';
+ while (true) {
+ result = f->read_unlocked(&c, 1);
+ if (result.has_error())
+ return Error(result.error);
+ if (result.value != 1 || c == '\n')
+ break;
+ truncated = true;
+ }
+ }
+
+ if (f->error_unlocked())
+ return Error(EIO);
+
+ // If the line ended with a newline, strip it.
+ if (!read_span.empty() && read_span.back() == '\n')
+ --bytes_read;
+
+ buf[bytes_read] = '\0';
+ return ReadLineResult{bytes_read, truncated, eof};
+ }
+
+ // Reads a single line into a caller-owned buffer, growing it as needed so
+ // that arbitrarily long records can be read. Otherwise behaves as read_line;
+ // the result is never truncated.
+ LIBC_INLINE static ErrorOr<ReadLineResult>
+ read_line_growing(File *f, DynamicBuffer &buf) {
+ if (!f)
+ return Error(EINVAL);
+
+ File::FileLock lock(f);
+ size_t bytes_read = 0;
+
+ while (true) {
+ // One byte for the character about to be read, one for the terminator.
+ if (bytes_read > cpp::numeric_limits<size_t>::max() - 2 ||
+ !buf.reserve(bytes_read + 2)) {
+ char c = '\0';
+ while (true) {
+ FileIOResult drain = f->read_unlocked(&c, 1);
+ if (drain.has_error())
+ return Error(drain.error);
+ if (drain.value != 1 || c == '\n')
+ break;
+ }
+ return Error(ENOMEM);
+ }
+
+ char ch = '\0';
+ FileIOResult result = f->read_unlocked(&ch, 1);
+ if (result.has_error())
+ return Error(result.error);
+ if (result.value != 1)
+ break;
+
+ buf.span()[bytes_read++] = ch;
+ if (ch == '\n')
+ break;
+ }
+
+ if (f->error_unlocked())
+ return Error(EIO);
+
+ bool eof = (bytes_read == 0);
+
+ // If the line ended with a newline, strip it.
+ if (bytes_read > 0 && buf.span()[bytes_read - 1] == '\n')
+ --bytes_read;
+
+ buf.span()[bytes_read] = '\0';
+ return ReadLineResult{bytes_read, /*truncated=*/false, eof};
+ }
+
+public:
+ LIBC_INLINE constexpr explicit FlatFileDatabase(const char *path)
+ : file_path(path) {}
+
+ FlatFileDatabase(const FlatFileDatabase &) = delete;
+ FlatFileDatabase &operator=(const FlatFileDatabase &) = delete;
+
+ // Sets or overrides the file path for database operations.
+ LIBC_INLINE void set_path(const char *path) {
+ if (!path)
+ return;
+ clear_file_stream();
+ file_path = path;
+ }
+
+ // Opens or rewinds the database file stream.
+ LIBC_INLINE ErrorOr<void> setdb() {
+ if (!file) {
+ auto result = openfile(file_path, "r");
+ if (!result.has_value())
+ return Error(result.error());
+ file = result.value();
+ return {};
+ }
+ auto result = file->seek(0, SEEK_SET);
+ if (!result.has_value())
+ return Error(result.error());
+ file->clearerr();
+ return {};
+ }
+
+ // Closes the database file stream.
+ LIBC_INLINE ErrorOr<void> enddb() { return clear_file_stream(); }
+
+ // Reads and parses the next record from the database into a fixed buffer.
+ // Returns true if an entry was read, false if EOF was reached, or an Error on
+ // failure. Blank lines are skipped. A record that does not fit in the buffer
+ // is reported as ERANGE.
+ LIBC_INLINE ErrorOr<bool> getnext(EntryType *entry, cpp::span<char> buffer) {
+ if (!entry)
+ return Error(EINVAL);
+
+ if (!file) {
+ auto res = setdb();
+ if (!res.has_value())
+ return Error(res.error());
+ }
+
+ while (true) {
+ auto result = read_line(file, buffer);
+ if (!result.has_value())
+ return Error(result.error());
+
+ ReadLineResult res = result.value();
+ if (res.eof)
+ return false; // EOF
+
+ // Skip blank lines.
+ if (res.bytes_read == 0)
+ continue;
+
+ if (res.truncated)
+ return Error(ERANGE);
+
+ // Slicing at bytes_read + 1 includes the terminating null byte written
+ // by read_line; the remainder of the buffer serves as scratch space.
+ auto parse_res =
+ parse_line<EntryType>(buffer.first(res.bytes_read + 1),
+ buffer.subspan(res.bytes_read + 1), entry);
+ if (!parse_res.has_value())
+ return Error(parse_res.error());
+ return true;
+ }
+ }
+
+ // Reads and parses the next record from the database into a caller-owned
+ // buffer, growing it as needed. Behaves as the fixed-buffer overload except
+ // that a long record grows the buffer rather than producing ERANGE.
+ LIBC_INLINE ErrorOr<bool> getnext(EntryType *entry, DynamicBuffer &buffer) {
+ if (!entry)
+ return Error(EINVAL);
+
+ if (!file) {
+ auto res = setdb();
+ if (!res.has_value())
+ return Error(res.error());
+ }
+
+ while (true) {
+ auto result = read_line_growing(file, buffer);
+ if (!result.has_value())
+ return Error(result.error());
+
+ ReadLineResult res = result.value();
+ if (res.eof)
+ return false; // EOF
+
+ // Skip blank lines.
+ if (res.bytes_read == 0)
+ continue;
+
+ while (true) {
+ // Slicing at bytes_read + 1 includes the terminating null byte written
+ // by read_line_growing; the remainder of the buffer serves as scratch
+ // space.
+ auto parse_res = parse_line<EntryType>(
+ buffer.span().first(res.bytes_read + 1),
+ buffer.span().subspan(res.bytes_read + 1), entry);
+ if (parse_res.has_value())
+ return true;
+ if (parse_res.error() != ERANGE)
+ return Error(parse_res.error());
+ if (!buffer.grow())
+ return Error(ENOMEM);
+ }
+ }
+ }
+
+ // Searches for a record matching a given predicate. Returns true if the
+ // entry was found, false if it's missing, or an Error if lookup failed.
+ //
+ // When BufferType is cpp::span<char>, lookup never allocates and returns
+ // ERANGE if any record encountered exceeds buffer (matching glibc and
+ // FreeBSD). When BufferType is DynamicBuffer, the buffer grows as needed.
+ template <typename BufferType>
+ LIBC_INLINE ErrorOr<bool> lookup(const Matcher &matcher, EntryType *entry,
+ BufferType &buffer) {
+ if (!entry)
+ return Error(EINVAL);
+
+ auto res = setdb();
+ if (!res.has_value())
+ return Error(res.error());
+
+ while (true) {
+ auto next_res = getnext(entry, buffer);
+ if (!next_res.has_value())
+ return Error(next_res.error());
+ if (!next_res.value())
+ return false; // EOF without match
+ if (matcher(*entry))
+ return true;
+ }
+ }
+};
+
+// RAII wrapper around FlatFileDatabase for stack-local database operations.
+// Automatically closes the database file stream on destruction.
+template <typename EntryType>
+class ScopedFlatFileDatabase : public FlatFileDatabase<EntryType> {
+public:
+ using FlatFileDatabase<EntryType>::FlatFileDatabase;
+
+ LIBC_INLINE ~ScopedFlatFileDatabase() { this->enddb(); }
+};
+
+} // namespace pwd
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_PWD_FLAT_FILE_DB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/threads/CMakeLists.txt
index 67a176f87a9..dde3ee34f3a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/CMakeLists.txt
@@ -36,6 +36,17 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()
+if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.tcb)
+ add_header_library(
+ tcb
+ HDRS
+ tcb.h
+ DEPENDS
+ .${LIBC_TARGET_OS}.tcb
+ libc.src.__support.macros.properties.os
+ )
+endif()
+
if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.futex_utils)
add_header_library(
futex_utils
@@ -124,6 +135,7 @@ add_header_library(
HDRS
thread.h
DEPENDS
+ .tcb
.thread_attributes
libc.hdr.stdint_proxy
libc.hdr.types.struct_sched_param
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/CMakeLists.txt
index 7d349f6d9bd..ae449c1af79 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/CMakeLists.txt
@@ -1,3 +1,19 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE}/tcb.h)
+ add_header_library(
+ tcb
+ HDRS
+ tcb.h
+ ${LIBC_TARGET_ARCHITECTURE}/tcb.h
+ DEPENDS
+ libc.hdr.offsetof_macros
+ libc.hdr.stdint_proxy
+ libc.src.__support.threads.thread_attributes
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.architectures
+ )
+endif()
+
add_header_library(
futex_word_type
HDRS
@@ -35,6 +51,7 @@ add_object_library(
libc.hdr.fcntl_macros
libc.hdr.errno_macros
libc.hdr.sched_macros
+ libc.hdr.signal_macros
libc.hdr.sys_mman_macros
libc.src.errno.errno
libc.src.__support.CPP.atomic
@@ -43,6 +60,7 @@ add_object_library(
libc.src.__support.common
libc.src.__support.error_or
libc.src.__support.OSUtil.linux.syscall_wrappers.close
+ libc.src.__support.OSUtil.linux.syscall_wrappers.getpid
libc.src.__support.OSUtil.linux.syscall_wrappers.mmap
libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect
libc.src.__support.OSUtil.linux.syscall_wrappers.munmap
@@ -51,8 +69,10 @@ add_object_library(
libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getparam
libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getscheduler
libc.src.__support.OSUtil.linux.syscall_wrappers.sched_setscheduler
+ libc.src.__support.OSUtil.linux.syscall_wrappers.tgkill
libc.src.__support.OSUtil.linux.syscall_wrappers.write
libc.src.__support.threads.thread_common
+ libc.src.__support.threads.thread_attributes
COMPILE_OPTIONS
${libc_opt_high_flag}
-fno-omit-frame-pointer # This allows us to sniff out the thread args from
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/aarch64/tcb.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/aarch64/tcb.h
new file mode 100644
index 00000000000..8a2d6a408b9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/aarch64/tcb.h
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines the Thread Control Block (TCB) for Linux AArch64.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_AARCH64_TCB_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_AARCH64_TCB_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/thread_attributes.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+struct ThreadControlBlock {
+ uintptr_t dtv;
+ ThreadAttributes *attrib;
+};
+
+LIBC_INLINE ThreadControlBlock *get_tcb() {
+ ThreadControlBlock *tp;
+ asm("mrs %0, tpidr_el0" : "=r"(tp));
+ return tp;
+}
+
+LIBC_INLINE ThreadControlBlock *get_tcb(uintptr_t tp) {
+ return reinterpret_cast<ThreadControlBlock *>(tp);
+}
+
+LIBC_INLINE ThreadAttributes *get_current_thread_attrib() {
+ return get_tcb()->attrib;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_AARCH64_TCB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/riscv/tcb.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/riscv/tcb.h
new file mode 100644
index 00000000000..f4e0a1314ef
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/riscv/tcb.h
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines the Thread Control Block (TCB) for Linux RISC-V.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RISCV_TCB_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RISCV_TCB_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/thread_attributes.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+struct ThreadControlBlock {
+ uintptr_t dtv;
+ ThreadAttributes *attrib;
+};
+
+LIBC_INLINE ThreadControlBlock *get_tcb() {
+ ThreadControlBlock *tp;
+ asm("mv %0, tp" : "=r"(tp));
+ return tp - 1;
+}
+
+LIBC_INLINE ThreadControlBlock *get_tcb(uintptr_t tp) {
+ return reinterpret_cast<ThreadControlBlock *>(tp) - 1;
+}
+
+LIBC_INLINE ThreadAttributes *get_current_thread_attrib() {
+ return get_tcb()->attrib;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RISCV_TCB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/tcb.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/tcb.h
new file mode 100644
index 00000000000..e9abd07423a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/tcb.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines Linux architecture-level Thread Control Block dispatcher.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_TCB_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_TCB_H
+
+#include "src/__support/macros/properties/architectures.h"
+
+#if defined(LIBC_TARGET_ARCH_IS_X86_64)
+#include "src/__support/threads/linux/x86_64/tcb.h"
+#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)
+#include "src/__support/threads/linux/aarch64/tcb.h"
+#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
+#include "src/__support/threads/linux/riscv/tcb.h"
+#else
+#error "Unsupported architecture for Linux Thread Control Block"
+#endif
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_TCB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/thread.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/thread.cpp
index 231b7cf2903..efbdc4a45d3 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/thread.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/thread.cpp
@@ -12,6 +12,7 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/stringstream.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getpid.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/mmap.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/mprotect.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/munmap.h"
@@ -20,6 +21,7 @@
#include "src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/tgkill.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/write.h"
#include "src/__support/OSUtil/syscall.h" // For syscall functions.
#include "src/__support/common.h"
@@ -27,6 +29,8 @@
#include "src/__support/libc_errno.h" // For error macros
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h" // For FutexWordType
+#include "src/__support/threads/linux/futex_word.h"
+#include "src/__support/threads/thread_attributes.h"
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
#include <arm_acle.h>
@@ -35,6 +39,7 @@
#include "hdr/errno_macros.h"
#include "hdr/fcntl_macros.h"
#include "hdr/sched_macros.h" // For CLONE_* flags.
+#include "hdr/signal_macros.h"
#include "hdr/stdint_proxy.h"
#include "hdr/sys_mman_macros.h" // For PROT_* and MAP_* definitions.
#include <linux/param.h> // For EXEC_PAGESIZE.
@@ -44,7 +49,6 @@
namespace LIBC_NAMESPACE_DECL {
static constexpr size_t NAME_SIZE_MAX = 16; // Includes the null terminator
-static constexpr uint32_t CLEAR_TID_VALUE = 0xABCD1234;
static constexpr unsigned CLONE_SYSCALL_FLAGS =
CLONE_VM // Share the memory space with the parent.
| CLONE_FS // Share the file system with the parent.
@@ -180,19 +184,13 @@ cleanup_thread_resources(ThreadAttributes *attrib) {
[[gnu::noinline]] void start_thread() {
auto *start_args = reinterpret_cast<StartArgs *>(get_start_args_addr());
auto *attrib = start_args->thread_attrib;
- internal::self.attrib = attrib;
- attrib->atexit_callback_mgr = internal::get_thread_atexit_callback_mgr();
if (attrib->style == ThreadStyle::POSIX) {
- attrib->retval.posix_retval =
- start_args->runner.posix_runner(start_args->arg);
- thread_exit(ThreadReturnValue(attrib->retval.posix_retval),
- ThreadStyle::POSIX);
+ ThreadReturnValue retval = start_args->runner.posix_runner(start_args->arg);
+ thread_exit(retval, ThreadStyle::POSIX);
} else {
- attrib->retval.stdc_retval =
- start_args->runner.stdc_runner(start_args->arg);
- thread_exit(ThreadReturnValue(attrib->retval.stdc_retval),
- ThreadStyle::STDC);
+ ThreadReturnValue retval = start_args->runner.stdc_runner(start_args->arg);
+ thread_exit(retval, ThreadStyle::STDC);
}
}
@@ -223,6 +221,10 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
else
stack = alloc.value();
owned_stack = true;
+ } else {
+ // The user is responsible for setting up the stack guard (or not) for the
+ // provided stack.
+ guardsize = 0;
}
// Validate that stack/stacksize are validly aligned.
@@ -291,9 +293,11 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
auto clear_tid = reinterpret_cast<Futex *>(
adjusted_stack + sizeof(StartArgs) + sizeof(ThreadAttributes));
- clear_tid->set(CLEAR_TID_VALUE);
+ clear_tid->set(1);
attrib->platform_data = clear_tid;
+ get_tcb(tls.tp)->attrib = attrib;
+
// The clone syscall takes arguments in an architecture specific order.
// Also, we want the result of the syscall to be in a register as the child
// thread gets a completely different stack after it is created. The stack
@@ -399,8 +403,9 @@ void Thread::wait() {
auto *clear_tid = reinterpret_cast<Futex *>(attrib->platform_data);
// We cannot do a FUTEX_WAIT_PRIVATE here as the kernel does a
// FUTEX_WAKE and not a FUTEX_WAKE_PRIVATE.
- while (clear_tid->load() != 0)
- clear_tid->wait(CLEAR_TID_VALUE, cpp::nullopt, true);
+ FutexWordType clear_tid_value;
+ while ((clear_tid_value = clear_tid->load()) != 0)
+ clear_tid->wait(clear_tid_value, cpp::nullopt, true);
}
bool Thread::operator==(const Thread &thread) const {
@@ -515,8 +520,45 @@ ErrorOr<SchedParameters> Thread::getschedparam() const {
return SchedParameters{pol_result.value(), param};
}
+ErrorOr<void> Thread::kill(int sig) {
+ auto state = static_cast<DetachState>(
+ attrib->detach_state.load(cpp::MemoryOrder::RELAXED));
+ switch (state) {
+ case DetachState::EXITING:
+ // The thread is exiting, or has already exited. POSIX.1-2024 requires that
+ // pthread_kill does not return ESRCH because the pthread_t (unlike the OS
+ // TID) is still valid. Calling tgkill would return ESRCH (or target a
+ // recycled TID), so we return success directly. We only need to "request
+ // that a signal be delivered", and not actually make sure it has been
+ // handled. A zombie thread cannot handle signals.
+ return {};
+ case DetachState::JOINABLE:
+ case DetachState::DETACHED:
+ // A thread in these states can handle a signal. Note that a JOINABLE thread
+ // can transition to the EXITING state at any moment (and a DETACHED thread
+ // can disappear), but we're not allowed to take any locks to prevent that
+ // from happening (this function needs to be async-signal-safe).
+ break;
+ }
+
+ pid_t pid = linux_syscalls::getpid();
+ auto result = linux_syscalls::tgkill(pid, attrib->tid, sig);
+
+ if (!result.has_value()) {
+ if (result.error() == ESRCH) {
+ // Either the thread has exited since we've checked its state, or this
+ // object is corrupted. The latter is UB, so we're going to assume the
+ // former.
+ return {};
+ }
+ return Error(result.error());
+ }
+ return {};
+}
+
void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
auto attrib = current_thread().attrib;
+ attrib->retval = retval;
// The very first thing we do is to call the thread's atexit callbacks.
// These callbacks could be the ones registered by the language runtimes,
@@ -526,7 +568,7 @@ void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
// cleanup_thread_resources function as that function can be called from a
// different thread. The destructors of thread local and TSS objects should
// be called by the thread which owns them.
- internal::call_atexit_callbacks(attrib);
+ internal::call_atexit_callbacks();
uint32_t joinable_state = uint32_t(DetachState::JOINABLE);
if (!attrib->detach_state.compare_exchange_strong(
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/x86_64/tcb.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/x86_64/tcb.h
new file mode 100644
index 00000000000..7b9242690f8
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/linux/x86_64/tcb.h
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines the Thread Control Block (TCB) for Linux x86_64.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_X86_64_TCB_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_X86_64_TCB_H
+
+#include "hdr/offsetof_macros.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/thread_attributes.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+struct ThreadControlBlock {
+ uintptr_t self;
+ uintptr_t dtv;
+ ThreadAttributes *attrib;
+ uintptr_t reserved[2];
+ uintptr_t stack_guard;
+};
+static_assert(offsetof(ThreadControlBlock, stack_guard) == 0x28,
+ "Offset defined by the ABI");
+
+LIBC_INLINE ThreadControlBlock *get_tcb() {
+ ThreadControlBlock *tcb;
+ asm("mov %%fs:0, %0" : "=r"(tcb));
+ return tcb;
+}
+
+LIBC_INLINE ThreadControlBlock *get_tcb(uintptr_t tp) {
+ return reinterpret_cast<ThreadControlBlock *>(tp);
+}
+
+LIBC_INLINE ThreadAttributes *get_current_thread_attrib() {
+ ThreadAttributes *attrib;
+ asm("mov %%fs:%c1, %0"
+ : "=r"(attrib)
+ : "i"(offsetof(ThreadControlBlock, attrib)));
+ return attrib;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_X86_64_TCB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/tcb.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/tcb.h
new file mode 100644
index 00000000000..04af422c35d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/tcb.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines OS-level Thread Control Block dispatcher.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_TCB_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_TCB_H
+
+#include "src/__support/macros/properties/os.h"
+
+#if defined(LIBC_TARGET_OS_IS_LINUX)
+#include "src/__support/threads/linux/tcb.h"
+#else
+#error "Unsupported OS for Thread Control Block"
+#endif
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_TCB_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.cpp
index 31c230a45b5..abcf7e399c1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.cpp
@@ -150,12 +150,8 @@ extern "C" int __cxa_thread_atexit_impl(AtExitCallback *callback, void *obj,
namespace internal {
-ThreadAtExitCallbackMgr *get_thread_atexit_callback_mgr() {
- return &atexit_callback_mgr;
-}
-
-void call_atexit_callbacks(ThreadAttributes *attrib) {
- attrib->atexit_callback_mgr->call();
+void call_atexit_callbacks() {
+ atexit_callback_mgr.call();
for (size_t i = 0; i < TSS_KEY_COUNT; ++i) {
TSSValueUnit &unit = tss_values[i];
// Both dtor and value need to nonnull to call dtor
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.h
index c42f87a1a3c..9971dc5f193 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread.h
@@ -19,6 +19,7 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/threads/tcb.h"
#include "src/__support/threads/thread_attributes.h"
// TODO: fix this unguarded linux dep
@@ -151,6 +152,9 @@ struct Thread {
// Get the scheduling policy and parameters of the thread.
// Return SchedParameters on success, or an error number on failure.
ErrorOr<SchedParameters> getschedparam() const;
+
+ // Send a signal to the thread.
+ ErrorOr<void> kill(int sig);
};
// Platforms should implement this function.
@@ -160,21 +164,15 @@ namespace internal {
// Internal namespace containing utilities which are to be used by platform
// implementations of threads.
-// Return the current thread's atexit callback manager. After thread startup
-// but before running the thread function, platform implementations should
-// set the "atexit_callback_mgr" field of the thread's attributes to the value
-// returned by this function.
-ThreadAtExitCallbackMgr *get_thread_atexit_callback_mgr();
-
// Call the currently registered thread specific atexit callbacks. Useful for
// implementing the thread_exit function.
-void call_atexit_callbacks(ThreadAttributes *attrib);
-
-LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self;
+void call_atexit_callbacks();
} // namespace internal
-LIBC_INLINE Thread current_thread() { return internal::self; }
+LIBC_INLINE Thread current_thread() {
+ return Thread(get_current_thread_attrib());
+}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread_attributes.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread_attributes.h
index 6225837ed77..123b0d2a6c8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread_attributes.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread_attributes.h
@@ -67,8 +67,6 @@ enum class DetachType : int {
CLEANUP = 2
};
-class ThreadAtExitCallbackMgr;
-
// A data type to hold common thread attributes which have to be stored as
// thread state. Note that this is different from public attribute types like
// pthread_attr_t which might contain information which need not be saved as
@@ -105,15 +103,14 @@ struct alignas(STACK_ALIGNMENT) ThreadAttributes {
int tid;
ThreadStyle style;
ThreadReturnValue retval;
- ThreadAtExitCallbackMgr *atexit_callback_mgr;
void *platform_data;
cpp::Atomic<ThreadAttributes *> joiner;
LIBC_INLINE constexpr ThreadAttributes()
: detach_state(uint32_t(DetachState::DETACHED)), stack(nullptr),
stacksize(0), guardsize(0), tls(0), tls_size(0), owned_stack(false),
- tid(-1), style(ThreadStyle::POSIX), retval(),
- atexit_callback_mgr(nullptr), platform_data(nullptr), joiner(nullptr) {}
+ tid(-1), style(ThreadStyle::POSIX), retval(), platform_data(nullptr),
+ joiner(nullptr) {}
};
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/tlsf_table.h b/deps/v8/third_party/llvm-libc/src/src/__support/tlsf_table.h
index a302fba15f1..e75f1074ca4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/tlsf_table.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/tlsf_table.h
@@ -32,7 +32,7 @@ struct DefaultFreeStoreConfig {
static constexpr size_t UNIT_SIZE = BlockRef::MIN_ALIGN;
static constexpr size_t STEP_SIZE_BITS = 3;
static constexpr size_t NUM_STEP_BITS = 2;
- static constexpr size_t NUM_TABLE_ENTRIES = sizeof(uintptr_t) == 8 ? 3 : 6;
+ static constexpr size_t NUM_TABLE_ENTRIES = 3;
static constexpr bool USE_TRIE_FOR_OVERFLOW_BIN = true;
static constexpr size_t LINEAR_SCAN_LIMIT = 16;
};
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/wctype/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/wctype/CMakeLists.txt
index bb67e72d001..d87d638ef28 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/wctype/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/wctype/CMakeLists.txt
@@ -12,6 +12,7 @@ add_header_library(
libc.src.__support.CPP.string
libc.src.__support.CPP.tuple
libc.src.__support.CPP.type_traits
+ libc.src.__support.CPP.utility
libc.src.__support.OSUtil.osutil
libc.src.__support.macros.config
libc.src.__support.math.ceil
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/wctype/perfect_hash_map.h b/deps/v8/third_party/llvm-libc/src/src/__support/wctype/perfect_hash_map.h
index a5562d589bf..91b33c8655a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/wctype/perfect_hash_map.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/wctype/perfect_hash_map.h
@@ -1,10 +1,15 @@
-//===-- Perfect hash map for conversion functions ---------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Perfect hash map for conversion functions.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_WCTYPE_PERFECT_HASH_MAP_H
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_PERFECT_HASH_MAP_H
@@ -18,6 +23,7 @@
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/tuple.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/CPP/utility/swap.h"
#include "src/__support/macros/config.h"
#include "src/__support/math/ceil.h"
#include "src/__support/math/log.h"
@@ -349,11 +355,8 @@ public:
sort_parts(size_t shard, cpp::array<uint64_t, n_> hashes) const {
for (size_t i = 0; i < hashes.size(); i++) {
for (size_t j = i + 1; j < hashes.size(); j++) {
- if (hashes[i] > hashes[j]) {
- auto temp = hashes[i];
- hashes[i] = hashes[j];
- hashes[j] = temp;
- }
+ if (hashes[i] > hashes[j])
+ cpp::swap(hashes[i], hashes[j]);
}
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/wctype_utils.h b/deps/v8/third_party/llvm-libc/src/src/__support/wctype_utils.h
index 4d0ecd2c1c0..633c9139f73 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/wctype_utils.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/wctype_utils.h
@@ -10,6 +10,7 @@
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
#include "hdr/types/wchar_t.h"
+#include "src/__support/CPP/bit.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
@@ -796,6 +797,17 @@ is_char_or_wchar(wchar_t ch, [[maybe_unused]] char, wchar_t wc_value) {
return (ch == wc_value);
}
+// Returns a three-way comparison between two wide character code points.
+LIBC_INLINE int threeway_cmp_single(wchar_t left, wchar_t right) {
+ // Valid UTF-32 code points are in [0, 0x10FFFF]. If invalid code points were
+ // treated as UB, the comparison below could done with 32-bit arithmetic.
+ if (left == right)
+ return 0;
+ if (left < right)
+ return -1;
+ return 1;
+}
+
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/rapidhash-v8/secret.h b/deps/v8/third_party/rapidhash-v8/secret.h
index 021125bc4ce..f6243199a14 100644
--- a/deps/v8/third_party/rapidhash-v8/secret.h
+++ b/deps/v8/third_party/rapidhash-v8/secret.h
@@ -81,6 +81,12 @@ static inline uint64_t wyrand(uint64_t* seed) {
static inline unsigned long long mul_mod(unsigned long long a,
unsigned long long b,
unsigned long long m) {
+#if defined(__SIZEOF_INT128__) && !defined(_WIN32)
+ // A 128-bit multiply and modulo lower to __umodti3 from compiler-rt, which
+ // clang's Windows runtime does not provide.
+ return static_cast<unsigned long long>(
+ (static_cast<__uint128_t>(a) * b) % m);
+#else
unsigned long long r = 0;
while (b) {
if (b & 1) {
@@ -96,6 +102,7 @@ static inline unsigned long long mul_mod(unsigned long long a,
}
}
return r;
+#endif
}
static inline unsigned long long pow_mod(unsigned long long a,
diff --git a/deps/v8/third_party/zlib/BUILD.gn b/deps/v8/third_party/zlib/BUILD.gn
index c37b4252961..29248e1da41 100644
--- a/deps/v8/third_party/zlib/BUILD.gn
+++ b/deps/v8/third_party/zlib/BUILD.gn
@@ -375,8 +375,6 @@ component("zlib") {
# Must be after no_chromium_code for warning flags to be ordered correctly.
":zlib_warnings",
]
-
- allow_circular_includes_from = deps
}
config("minizip_warnings") {
diff --git a/deps/v8/third_party/zlib/chromeconf.h b/deps/v8/third_party/zlib/chromeconf.h
index c713e2119b4..77f0e29e0d6 100644
--- a/deps/v8/third_party/zlib/chromeconf.h
+++ b/deps/v8/third_party/zlib/chromeconf.h
@@ -207,8 +207,5 @@
/* Symbols added by cpu_features.c */
#define cpu_check_features Cr_z_cpu_check_features
#define x86_cpu_enable_sse2 Cr_z_x86_cpu_enable_sse2
-#define x86_cpu_enable_avx512 Cr_z_x86_cpu_enable_avx512
-#define riscv_cpu_enable_rvv Cr_z_riscv_cpu_enable_rvv
-#define riscv_cpu_enable_vclmul Cr_z_riscv_cpu_enable_vclmul
#endif /* THIRD_PARTY_ZLIB_CHROMECONF_H_ */
diff --git a/deps/v8/tools/clusterfuzz/js_fuzzer/resources/differential_fuzz_v8.js b/deps/v8/tools/clusterfuzz/js_fuzzer/resources/differential_fuzz_v8.js
index 2c51c1d33ad..de8a2d7be93 100644
--- a/deps/v8/tools/clusterfuzz/js_fuzzer/resources/differential_fuzz_v8.js
+++ b/deps/v8/tools/clusterfuzz/js_fuzzer/resources/differential_fuzz_v8.js
@@ -20,6 +20,8 @@ assertNotNull = (value, name_opt) => { __prettyPrint(value); };
// Suppress optimization status as it leads to false positives.
assertUnoptimized = () => {};
assertOptimized = () => {};
+assertMaglevved = () => {};
+assertNotMaglevved = () => {};
isNeverOptimize = () => {};
isInterpreted = () => {};
isBaseline = () => {};
diff --git a/deps/v8/tools/clusterfuzz/js_fuzzer/resources/sandbox.js b/deps/v8/tools/clusterfuzz/js_fuzzer/resources/sandbox.js
index 318c5c67b69..f172927ed17 100644
--- a/deps/v8/tools/clusterfuzz/js_fuzzer/resources/sandbox.js
+++ b/deps/v8/tools/clusterfuzz/js_fuzzer/resources/sandbox.js
@@ -24,5 +24,6 @@ try {
getInstanceTypeIdOfObjectAt: () => undefined,
getInstanceTypeIdFor: () => 0,
getFieldOffset: () => 31,
+ getMetadata: () => ({trustedPointerHandleShift: 9}),
};
}
diff --git a/deps/v8/tools/clusterfuzz/js_fuzzer/test_data/sandbox/load_expected.js b/deps/v8/tools/clusterfuzz/js_fuzzer/test_data/sandbox/load_expected.js
index a1b8f6f772d..8b6e95e6702 100644
--- a/deps/v8/tools/clusterfuzz/js_fuzzer/test_data/sandbox/load_expected.js
+++ b/deps/v8/tools/clusterfuzz/js_fuzzer/test_data/sandbox/load_expected.js
@@ -22,7 +22,10 @@ try {
getInstanceTypeIdOf: () => undefined,
getInstanceTypeIdOfObjectAt: () => undefined,
getInstanceTypeIdFor: () => 0,
- getFieldOffset: () => 31
+ getFieldOffset: () => 31,
+ getMetadata: () => ({
+ trustedPointerHandleShift: 9
+ })
};
}
diff --git a/deps/v8/tools/debug_helper/BUILD.gn b/deps/v8/tools/debug_helper/BUILD.gn
index 1c0265a6368..887990544f9 100644
--- a/deps/v8/tools/debug_helper/BUILD.gn
+++ b/deps/v8/tools/debug_helper/BUILD.gn
@@ -167,6 +167,7 @@ v8_executable("corruption_harness") {
deps = [
"../..:v8",
+ "../..:v8_internal_headers",
"../..:v8_libbase",
"../..:v8_libplatform",
"../..:v8_tracing",
diff --git a/deps/v8/tools/metagen/cpp_hier.py b/deps/v8/tools/metagen/cpp_hier.py
index 9383c6d8694..f81288ddf2d 100644
--- a/deps/v8/tools/metagen/cpp_hier.py
+++ b/deps/v8/tools/metagen/cpp_hier.py
@@ -238,7 +238,10 @@ def scan_cpp(v8_root: str,
(-I../../v8/src, --sysroot=../../build/..., ...) resolve the same way
clang itself would resolve them in the build.
"""
- driver_path = os.path.abspath(driver_path)
+ # Prefix the source with '.' so neither clang nor clang-cl can parse a
+ # leading '-' or '/' as an option.
+ driver_path = os.path.join(
+ ".", os.path.relpath(os.path.abspath(driver_path), parse_cwd))
options = (
cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD
| cindex.TranslationUnit.PARSE_SKIP_FUNCTION_BODIES)
diff --git a/deps/v8/tools/wasm/BUILD.gn b/deps/v8/tools/wasm/BUILD.gn
index 16701009734..886ec0b4713 100644
--- a/deps/v8/tools/wasm/BUILD.gn
+++ b/deps/v8/tools/wasm/BUILD.gn
@@ -21,6 +21,7 @@ v8_executable("wami") {
deps = [
"../..:v8",
+ "../..:v8_internal_headers",
"../..:v8_libbase",
"../..:v8_libplatform",
]